mirror of
https://github.com/psviderski/uncloud.git
synced 2026-11-10 20:54:17 +00:00
fix(compose): strip and resolve pre-deploy hook secrets like service env (#424)
* fix(compose): strip and resolve pre-deploy hook secrets like service env (fixes #422) normaliseContainerForStore only cleared Config.Env and ServiceSpec.Container.Env before writing a container record to the replicated Corrosion store, leaving ServiceSpec.PreDeploy.Env in place. A secret set via x-pre_deploy.environment therefore replicated to every machine in the cluster, unlike the same value set via environment. ResolveSecrets had the same asymmetry in the other direction: it only resolved secret://name references in service.Environment, so a reference placed in the pre-deploy hook's environment passed through unresolved as a literal string. HasCommandSecretRefs is extended the same way for consistency. Add tests pinning both behaviours. * update docs that secret references are available for pre-deploy hooks --------- Co-authored-by: Pasha Sviderski <me@psviderski.name>
This commit is contained in:
co-authored by
Pasha Sviderski
parent
ce1c6bd05a
commit
8ddbe3c606
@@ -328,6 +328,74 @@ secrets:
|
||||
assert.Equal(t, "run\n", string(runs), "command should run exactly once across services and repeated resolutions")
|
||||
}
|
||||
|
||||
// TestResolveSecrets_PreDeployHook pins the behaviour that 'secret://name' references in the pre-deploy hook's
|
||||
// environment are resolved just like references in the service's own environment.
|
||||
// See https://github.com/psviderski/uncloud/issues/422.
|
||||
func TestResolveSecrets_PreDeployHook(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
content := `
|
||||
services:
|
||||
foo:
|
||||
image: foo
|
||||
environment:
|
||||
CONTROL_TOKEN: secret://control_token
|
||||
x-pre_deploy:
|
||||
command: ["./migrate.sh"]
|
||||
environment:
|
||||
HOOK_TOKEN: secret://hook_token
|
||||
PLAIN: hello
|
||||
secrets:
|
||||
control_token:
|
||||
x-command: printf control-value
|
||||
hook_token:
|
||||
x-command: printf hook-value
|
||||
`
|
||||
project := loadProject(t, content)
|
||||
require.NoError(t, ResolveSecrets(context.Background(), project))
|
||||
|
||||
assert.Equal(t, env(map[string]string{"CONTROL_TOKEN": "control-value"}), project.Services["foo"].Environment)
|
||||
|
||||
hook, ok := project.Services["foo"].Extensions[PreDeployHookExtensionKey].(PreDeployHook)
|
||||
require.True(t, ok, "x-pre_deploy extension not found")
|
||||
assert.Equal(t, env(map[string]string{"HOOK_TOKEN": "hook-value", "PLAIN": "hello"}), hook.Environment)
|
||||
}
|
||||
|
||||
// TestResolveSecrets_PreDeployHook_ResolvedOnce verifies that a secret referenced from both the service's
|
||||
// environment and its pre-deploy hook's environment is only resolved once.
|
||||
func TestResolveSecrets_PreDeployHook_ResolvedOnce(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
counter := filepath.Join(t.TempDir(), "runs")
|
||||
content := fmt.Sprintf(`
|
||||
services:
|
||||
foo:
|
||||
image: foo
|
||||
environment:
|
||||
TOKEN: secret://token
|
||||
x-pre_deploy:
|
||||
command: ["./migrate.sh"]
|
||||
environment:
|
||||
TOKEN: secret://token
|
||||
secrets:
|
||||
token:
|
||||
x-command: "sh -c 'echo run >> %s; printf abc'"
|
||||
`, counter)
|
||||
|
||||
project := loadProject(t, content)
|
||||
require.NoError(t, ResolveSecrets(context.Background(), project))
|
||||
|
||||
assert.Equal(t, "abc", *project.Services["foo"].Environment["TOKEN"])
|
||||
hook, ok := project.Services["foo"].Extensions[PreDeployHookExtensionKey].(PreDeployHook)
|
||||
require.True(t, ok, "x-pre_deploy extension not found")
|
||||
assert.Equal(t, "abc", *hook.Environment["TOKEN"])
|
||||
|
||||
runs, err := os.ReadFile(counter)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "run\n", string(runs),
|
||||
"command should run exactly once across the service and hook environments")
|
||||
}
|
||||
|
||||
func TestHasCommandSecretRefs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -387,6 +455,22 @@ services:
|
||||
`,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "command secret referenced from pre-deploy hook",
|
||||
content: `
|
||||
services:
|
||||
foo:
|
||||
image: foo
|
||||
x-pre_deploy:
|
||||
command: ["./migrate.sh"]
|
||||
environment:
|
||||
TOKEN: secret://token
|
||||
secrets:
|
||||
token:
|
||||
x-command: printf abc
|
||||
`,
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user