Skip to content

Commit 1a500d8

Browse files
authored
prebuilt image deploy action secret handling (#865)
1 parent 0865f41 commit 1a500d8

2 files changed

Lines changed: 81 additions & 5 deletions

File tree

cmd/lk/agent.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -755,22 +755,37 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error {
755755
buildContext, cancel := context.WithTimeout(ctx, buildTimeout)
756756
defer cancel()
757757

758+
secrets, err := requireSecrets(ctx, cmd, false, true)
759+
if err != nil {
760+
return err
761+
}
762+
758763
// --image or --image-tar: skip source build and push a prebuilt image via the OCI proxy.
759764
imageRef := cmd.String("image")
760765
imageTar := cmd.String("image-tar")
761766
if imageRef != "" || imageTar != "" {
767+
if len(secrets) > 0 {
768+
resp, err := agentsClient.UpdateAgentSecrets(buildContext, &lkproto.UpdateAgentSecretsRequest{
769+
AgentId: agentId,
770+
Secrets: secrets,
771+
})
772+
if err != nil {
773+
if twerr, ok := err.(twirp.Error); ok {
774+
return fmt.Errorf("unable to update agent secrets: %s", twerr.Msg())
775+
}
776+
return fmt.Errorf("unable to update agent secrets: %w", err)
777+
}
778+
if !resp.Success {
779+
return fmt.Errorf("failed to update agent secrets: %s", resp.Message)
780+
}
781+
}
762782
if err := deployPrebuiltImage(buildContext, agentId, imageRef, imageTar); err != nil {
763783
return fmt.Errorf("unable to deploy prebuilt image: %w", err)
764784
}
765785
out.Status("Deployed agent")
766786
return nil
767787
}
768788

769-
secrets, err := requireSecrets(ctx, cmd, false, true)
770-
if err != nil {
771-
return err
772-
}
773-
774789
projectType, err := agentfs.DetectProjectType(os.DirFS(workingDir))
775790
if err != nil {
776791
return noAgentError()

cmd/lk/agent_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,67 @@ func TestRequireSecrets_InlineOverridesFile(t *testing.T) {
295295
assert.Equal(t, "inline_value", string(secrets[0].Value))
296296
}
297297

298+
// TestRequireSecrets_LazyDeployMode covers the secret-loading contract used by
299+
// `lk agent deploy` (required=false, lazy=true). Issue #860 depended on this path
300+
// being reached before the --image branch.
301+
func TestRequireSecrets_LazyDeployMode(t *testing.T) {
302+
tests := []struct {
303+
name string
304+
envFileContent string
305+
secretsFile string
306+
inlineSecrets []string
307+
expectedSecrets []string
308+
}{
309+
{
310+
name: "does not auto-read .env when lazy and no secrets flags",
311+
envFileContent: "FROM_ENV=should-not-appear",
312+
expectedSecrets: nil,
313+
},
314+
{
315+
name: "reads secrets when --secrets-file is explicitly set",
316+
envFileContent: "OTHER=ignored",
317+
secretsFile: ".env.production",
318+
expectedSecrets: []string{"API_KEY"},
319+
},
320+
{
321+
name: "uses inline --secrets without reading .env",
322+
envFileContent: "FROM_ENV=ignored",
323+
inlineSecrets: []string{"FROM_FLAG=value"},
324+
expectedSecrets: []string{"FROM_FLAG"},
325+
},
326+
}
327+
328+
for _, tt := range tests {
329+
t.Run(tt.name, func(t *testing.T) {
330+
tempDir, err := os.MkdirTemp("", "agent-secrets-lazy-test")
331+
require.NoError(t, err)
332+
defer os.RemoveAll(tempDir)
333+
334+
oldWd, _ := os.Getwd()
335+
require.NoError(t, os.Chdir(tempDir))
336+
defer os.Chdir(oldWd)
337+
338+
if tt.envFileContent != "" {
339+
require.NoError(t, os.WriteFile(".env", []byte(tt.envFileContent), 0644))
340+
}
341+
if tt.secretsFile != "" {
342+
require.NoError(t, os.WriteFile(tt.secretsFile, []byte("API_KEY=secret"), 0644))
343+
}
344+
345+
cmd := buildTestCommand(t, false, tt.secretsFile, tt.inlineSecrets)
346+
347+
secrets, err := requireSecrets(context.Background(), cmd, false, true)
348+
require.NoError(t, err)
349+
350+
secretNames := make([]string, len(secrets))
351+
for i, s := range secrets {
352+
secretNames[i] = s.Name
353+
}
354+
assert.ElementsMatch(t, tt.expectedSecrets, secretNames)
355+
})
356+
}
357+
}
358+
298359
// TestQuietFlagAlias verifies the global --quiet flag and its --silent / -q aliases all
299360
// resolve to the same value, so the former per-command --silent keeps working.
300361
func TestQuietFlagAlias(t *testing.T) {

0 commit comments

Comments
 (0)