From f812a4d483360ac12013d0f2deeadbee162d0434 Mon Sep 17 00:00:00 2001 From: Christina Chu Date: Tue, 27 Oct 2026 13:01:57 -0700 Subject: [PATCH 1/2] feat: turn on elevated actions in aws-devops-agent setup A full setup now turns on the elevatedActionsEnabled preference of the agent space. Setup sets it when it creates a space. On a reused space, setup reads the current preferences and sends them with the new one, because an update replaces all the preferences. A connect run does not change the preference. The --no-elevated-actions flag keeps the preference as it is. Co-Authored-By: Claude Opus 5.5 --- cmd/aws_devops_agent/confirm_test.go | 6 ++ cmd/aws_devops_agent/select_test.go | 4 + cmd/aws_devops_agent/setup.go | 40 +++++----- internal/awsdevops/awsdevops.go | 1 + internal/awsdevops/awsdevops_test.go | 113 ++++++++++++++++++++++++++- internal/awsdevops/setup.go | 57 ++++++++++++-- 6 files changed, 197 insertions(+), 24 deletions(-) diff --git a/cmd/aws_devops_agent/confirm_test.go b/cmd/aws_devops_agent/confirm_test.go index 8cd36ccf6..41e543770 100644 --- a/cmd/aws_devops_agent/confirm_test.go +++ b/cmd/aws_devops_agent/confirm_test.go @@ -71,6 +71,12 @@ func (a countingAgent) GetAgentSpace(_ context.Context, in *devopsagent.GetAgent return &devopsagent.GetAgentSpaceOutput{AgentSpace: &agenttypes.AgentSpace{AgentSpaceId: in.AgentSpaceId}}, nil } +func (a countingAgent) UpdateAgentSpace(context.Context, *devopsagent.UpdateAgentSpaceInput, ...func(*devopsagent.Options)) (*devopsagent.UpdateAgentSpaceOutput, error) { + a.writes.add("UpdateAgentSpace") + + return &devopsagent.UpdateAgentSpaceOutput{}, nil +} + func (a countingAgent) RegisterService(context.Context, *devopsagent.RegisterServiceInput, ...func(*devopsagent.Options)) (*devopsagent.RegisterServiceOutput, error) { a.writes.add("RegisterService") diff --git a/cmd/aws_devops_agent/select_test.go b/cmd/aws_devops_agent/select_test.go index 54458388d..6abe725bb 100644 --- a/cmd/aws_devops_agent/select_test.go +++ b/cmd/aws_devops_agent/select_test.go @@ -85,6 +85,10 @@ func (s stubAgent) GetAgentSpace(_ context.Context, in *devopsagent.GetAgentSpac return &devopsagent.GetAgentSpaceOutput{AgentSpace: &agenttypes.AgentSpace{AgentSpaceId: in.AgentSpaceId}}, nil } +func (s stubAgent) UpdateAgentSpace(context.Context, *devopsagent.UpdateAgentSpaceInput, ...func(*devopsagent.Options)) (*devopsagent.UpdateAgentSpaceOutput, error) { + return nil, nil +} + func (s stubAgent) ListAgentSpaces(context.Context, *devopsagent.ListAgentSpacesInput, ...func(*devopsagent.Options)) (*devopsagent.ListAgentSpacesOutput, error) { return &devopsagent.ListAgentSpacesOutput{AgentSpaces: s.spaces}, nil } diff --git a/cmd/aws_devops_agent/setup.go b/cmd/aws_devops_agent/setup.go index b8fac1048..d1b837089 100644 --- a/cmd/aws_devops_agent/setup.go +++ b/cmd/aws_devops_agent/setup.go @@ -27,6 +27,7 @@ const ( replaceMCPTokenFlag = "replace-mcp-token" mcpServiceIDFlag = "mcp-service-id" mcpEndpointFlag = "mcp-endpoint" + noElevatedFlag = "no-elevated-actions" yesFlag = "yes" ) @@ -40,10 +41,11 @@ LaunchDarkly MCP server connection the AWS DevOps Agent needs. When the account already has agent spaces, setup asks which one to connect LaunchDarkly to. On a space that setup did not make, setup only registers the MCP server. On a space that setup made, or with --auth-flow, setup runs the -full setup. Pass --agent-space-id to pick a space without the list, or ---new-agent-space to provision another space. A new space needs a name: pass ---agent-space-name, or type one when setup asks. The run ends with the -operator app URL, where the agent is used. +full setup. A full setup turns on elevated actions on the space, unless you +pass --no-elevated-actions. Pass --agent-space-id to pick a space without the +list, or --new-agent-space to provision another space. A new space needs a +name: pass --agent-space-name, or type one when setup asks. The run ends with +the operator app URL, where the agent is used. Each agent space gets its own LaunchDarkly MCP server registration, so each space can use a different token. The MCP server is connected with @@ -72,6 +74,7 @@ for --access-token.`, cmd.Flags().String(idpClientSecretFlag, "", "OIDC client secret, required when --auth-flow=idp") cmd.Flags().Bool(replaceMCPTokenFlag, false, "Give the agent space a new LaunchDarkly MCP server with the token passed with --access-token. Other agent spaces keep their server") cmd.Flags().String(mcpServiceIDFlag, "", "Registered MCP server to connect, instead of the server of the agent space") + cmd.Flags().Bool(noElevatedFlag, false, "Do not turn on elevated actions on the agent space. Elevated actions let the agent change AWS resources") cmd.Flags().String(mcpEndpointFlag, "", "MCP endpoint to register. Setup reuses only a server at this endpoint. Defaults to "+awsdevops.MCPServerEndpoint) cmd.Flags().Bool(yesFlag, false, "Ask no questions and accept every step") @@ -668,20 +671,21 @@ func askToken(cmd *cobra.Command, baseURI string) (string, error) { func setupOptions(cmd *cobra.Command) (awsdevops.SetupOptions, error) { opts := awsdevops.SetupOptions{ - AgentSpaceID: mustString(cmd, agentSpaceIDFlag), - AgentSpaceName: mustString(cmd, agentSpaceNameFlag), - AuthFlow: strings.ToLower(mustString(cmd, authFlowFlag)), - AuthFlowSet: cmd.Flags().Changed(authFlowFlag), - IdcInstanceARN: mustString(cmd, idcInstanceARNFlag), - IssuerURL: mustString(cmd, issuerURLFlag), - IdpClientID: mustString(cmd, idpClientIDFlag), - IdpClientSecret: mustString(cmd, idpClientSecretFlag), - NewAgentSpace: mustBool(cmd, newAgentSpaceFlag), - LDBaseURI: viper.GetString(cliflags.BaseURIFlag), - LDAccessToken: viper.GetString(cliflags.AccessTokenFlag), - ReplaceMCPToken: mustBool(cmd, replaceMCPTokenFlag), - MCPServiceID: mustString(cmd, mcpServiceIDFlag), - MCPEndpoint: mustString(cmd, mcpEndpointFlag), + AgentSpaceID: mustString(cmd, agentSpaceIDFlag), + AgentSpaceName: mustString(cmd, agentSpaceNameFlag), + AuthFlow: strings.ToLower(mustString(cmd, authFlowFlag)), + AuthFlowSet: cmd.Flags().Changed(authFlowFlag), + IdcInstanceARN: mustString(cmd, idcInstanceARNFlag), + IssuerURL: mustString(cmd, issuerURLFlag), + IdpClientID: mustString(cmd, idpClientIDFlag), + IdpClientSecret: mustString(cmd, idpClientSecretFlag), + NewAgentSpace: mustBool(cmd, newAgentSpaceFlag), + NoElevatedActions: mustBool(cmd, noElevatedFlag), + LDBaseURI: viper.GetString(cliflags.BaseURIFlag), + LDAccessToken: viper.GetString(cliflags.AccessTokenFlag), + ReplaceMCPToken: mustBool(cmd, replaceMCPTokenFlag), + MCPServiceID: mustString(cmd, mcpServiceIDFlag), + MCPEndpoint: mustString(cmd, mcpEndpointFlag), } idcSet := opts.IdcInstanceARN != "" diff --git a/internal/awsdevops/awsdevops.go b/internal/awsdevops/awsdevops.go index 72155518a..ae234bd8b 100644 --- a/internal/awsdevops/awsdevops.go +++ b/internal/awsdevops/awsdevops.go @@ -61,6 +61,7 @@ type AgentAPI interface { ListAssociations(context.Context, *devopsagent.ListAssociationsInput, ...func(*devopsagent.Options)) (*devopsagent.ListAssociationsOutput, error) ListServices(context.Context, *devopsagent.ListServicesInput, ...func(*devopsagent.Options)) (*devopsagent.ListServicesOutput, error) RegisterService(context.Context, *devopsagent.RegisterServiceInput, ...func(*devopsagent.Options)) (*devopsagent.RegisterServiceOutput, error) + UpdateAgentSpace(context.Context, *devopsagent.UpdateAgentSpaceInput, ...func(*devopsagent.Options)) (*devopsagent.UpdateAgentSpaceOutput, error) } // IAMAPI is the subset of the IAM API this package uses. diff --git a/internal/awsdevops/awsdevops_test.go b/internal/awsdevops/awsdevops_test.go index 6a0de2f5a..7fa01410b 100644 --- a/internal/awsdevops/awsdevops_test.go +++ b/internal/awsdevops/awsdevops_test.go @@ -34,6 +34,10 @@ type fakeAgent struct { tagsErrFor map[string]error // createdTags holds the tags of the created space. createdTags map[string]string + // createdPreferences holds the preferences of the created space. + createdPreferences map[string]bool + // updatedPreferences holds the preferences of each space update. + updatedPreferences []map[string]bool // goneSpaces makes GetAgentSpace report not found. goneSpaces map[string]bool getSpaceErr error @@ -108,6 +112,7 @@ func (f *fakeAgent) AssociateService(_ context.Context, in *devopsagent.Associat func (f *fakeAgent) CreateAgentSpace(_ context.Context, in *devopsagent.CreateAgentSpaceInput, _ ...func(*devopsagent.Options)) (*devopsagent.CreateAgentSpaceOutput, error) { f.calls = append(f.calls, "CreateAgentSpace") f.createdTags = in.Tags + f.createdPreferences = in.Preferences return &devopsagent.CreateAgentSpaceOutput{ AgentSpace: &agenttypes.AgentSpace{AgentSpaceId: aws.String("space-1")}, @@ -180,18 +185,32 @@ func (f *fakeAgent) GetAgentSpace(_ context.Context, in *devopsagent.GetAgentSpa } name := "launchdarkly" var description *string + var preferences map[string]bool for _, space := range f.agentSpaces { if aws.ToString(space.AgentSpaceId) == id && space.Name != nil { name = aws.ToString(space.Name) description = space.Description + preferences = space.Preferences } } return &devopsagent.GetAgentSpaceOutput{ - AgentSpace: &agenttypes.AgentSpace{AgentSpaceId: in.AgentSpaceId, Name: aws.String(name), Description: description}, + AgentSpace: &agenttypes.AgentSpace{ + AgentSpaceId: in.AgentSpaceId, + Name: aws.String(name), + Description: description, + Preferences: preferences, + }, }, nil } +func (f *fakeAgent) UpdateAgentSpace(_ context.Context, in *devopsagent.UpdateAgentSpaceInput, _ ...func(*devopsagent.Options)) (*devopsagent.UpdateAgentSpaceOutput, error) { + f.calls = append(f.calls, "UpdateAgentSpace") + f.updatedPreferences = append(f.updatedPreferences, in.Preferences) + + return &devopsagent.UpdateAgentSpaceOutput{}, nil +} + func (f *fakeAgent) ListAgentSpaces(_ context.Context, in *devopsagent.ListAgentSpacesInput, _ ...func(*devopsagent.Options)) (*devopsagent.ListAgentSpacesOutput, error) { spaces := f.agentSpaces if spaces == nil { @@ -904,3 +923,95 @@ func TestMCPAssociationClassifiesTheSkillTools(t *testing.T) { assert.Equal(t, agenttypes.ToolClassificationReadOnly, classes[tool], tool) } } + +func TestSetupTurnsOnElevatedActionsOnANewSpace(t *testing.T) { + agent := &fakeAgent{} + + _, err := awsdevops.Setup(context.Background(), newTestClients(agent, newFakeIAM()), awsdevops.SetupOptions{ + AgentSpaceName: "launchdarkly", + AuthFlow: "iam", + LDAccessToken: "api-token", + }) + require.NoError(t, err) + + assert.Equal(t, map[string]bool{awsdevops.ElevatedActionsPreference: true}, agent.createdPreferences) + assert.NotContains(t, agent.calls, "UpdateAgentSpace") +} + +func TestSetupTurnsOnElevatedActionsOnAReusedSpaceAndKeepsOtherPreferences(t *testing.T) { + agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ + AgentSpaceId: aws.String("space-existing"), + Name: aws.String("launchdarkly"), + Preferences: map[string]bool{"otherPreference": true}, + }}} + opts := awsdevops.SetupOptions{AgentSpaceName: "launchdarkly", AuthFlow: "iam"} + + plan, err := awsdevops.PlanSetup(context.Background(), newTestClients(agent, newFakeIAM()), opts, true) + require.NoError(t, err) + assert.Contains(t, plan.Text().AgentSpace, "turn on elevated actions") + + _, err = awsdevops.Setup(context.Background(), newTestClients(agent, newFakeIAM()), opts) + require.NoError(t, err) + + assert.Equal(t, []map[string]bool{{ + "otherPreference": true, + awsdevops.ElevatedActionsPreference: true, + }}, agent.updatedPreferences) +} + +func TestSetupLeavesASpaceWithElevatedActionsUnchanged(t *testing.T) { + agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ + AgentSpaceId: aws.String("space-existing"), + Name: aws.String("launchdarkly"), + Preferences: map[string]bool{awsdevops.ElevatedActionsPreference: true}, + }}} + + _, err := awsdevops.Setup(context.Background(), newTestClients(agent, newFakeIAM()), awsdevops.SetupOptions{ + AgentSpaceName: "launchdarkly", + AuthFlow: "iam", + }) + require.NoError(t, err) + + assert.NotContains(t, agent.calls, "UpdateAgentSpace") +} + +func TestSetupWithNoElevatedActionsKeepsThePreference(t *testing.T) { + agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ + AgentSpaceId: aws.String("space-existing"), + Name: aws.String("launchdarkly"), + }}} + + _, err := awsdevops.Setup(context.Background(), newTestClients(agent, newFakeIAM()), awsdevops.SetupOptions{ + AgentSpaceName: "launchdarkly", + AuthFlow: "iam", + NoElevatedActions: true, + }) + require.NoError(t, err) + assert.NotContains(t, agent.calls, "UpdateAgentSpace") + + created := &fakeAgent{} + _, err = awsdevops.Setup(context.Background(), newTestClients(created, newFakeIAM()), awsdevops.SetupOptions{ + AgentSpaceName: "fresh", + NewAgentSpace: true, + AuthFlow: "iam", + LDAccessToken: "api-token", + NoElevatedActions: true, + }) + require.NoError(t, err) + assert.Nil(t, created.createdPreferences) +} + +func TestPlanSetupConnectLeavesElevatedActionsUnchanged(t *testing.T) { + agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ + AgentSpaceId: aws.String("space-existing"), + Name: aws.String("launchdarkly"), + }}} + + plan, err := awsdevops.PlanSetup(context.Background(), newTestClients(agent, newFakeIAM()), awsdevops.SetupOptions{ + AgentSpaceID: "space-existing", + }, false) + require.NoError(t, err) + + assert.False(t, plan.Space.EnableElevated) + assert.NotContains(t, plan.Text().AgentSpace, "elevated") +} diff --git a/internal/awsdevops/setup.go b/internal/awsdevops/setup.go index 42a6a7cd8..4dd87d5b8 100644 --- a/internal/awsdevops/setup.go +++ b/internal/awsdevops/setup.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "maps" "slices" "strings" "time" @@ -43,6 +44,9 @@ const ( MCPServerEndpoint = "https://mcp.launchdarkly.com/mcp/launchdarkly" agentSpaceDescription = "Managed by the LaunchDarkly CLI" + // ElevatedActionsPreference lets the agent run actions that change AWS + // resources. + ElevatedActionsPreference = "elevatedActionsEnabled" ) // The agent invokes read-only tools without asking for approval, so anything @@ -94,6 +98,8 @@ type SetupOptions struct { AgentSpaceID string AgentSpaceName string NewAgentSpace bool + // NoElevatedActions keeps the elevated actions preference of the space. + NoElevatedActions bool AuthFlow string // AuthFlowSet: the user passed --auth-flow. @@ -187,17 +193,23 @@ type SpaceStep struct { Action SpaceAction ID string Name string + // EnableElevated turns on elevated actions on the space. + EnableElevated bool } func (s SpaceStep) describe() string { label := fmt.Sprintf("%s (%s)", s.Name, s.ID) + elevated := "" + if s.EnableElevated { + elevated = ", and turn on elevated actions" + } switch s.Action { case SpaceCreate: - return "Create agent space " + s.Name + return "Create agent space " + s.Name + elevated case SpaceConnect: return "Connect to agent space " + label default: - return "Reuse agent space " + label + return "Reuse agent space " + label + elevated } } @@ -581,7 +593,7 @@ func planAgentSpace(ctx context.Context, clients Clients, opts SetupOptions, pro return SpaceStep{}, errors.New("a new agent space needs a name. Pass --agent-space-name") } if id == "" { - return SpaceStep{Action: SpaceCreate, Name: opts.AgentSpaceName}, nil + return SpaceStep{Action: SpaceCreate, Name: opts.AgentSpaceName, EnableElevated: !opts.NoElevatedActions}, nil } space, err := clients.Agent.GetAgentSpace(ctx, &devopsagent.GetAgentSpaceInput{AgentSpaceId: aws.String(id)}) @@ -591,6 +603,8 @@ func planAgentSpace(ctx context.Context, clients Clients, opts SetupOptions, pro step := SpaceStep{Action: SpaceReuse, ID: id, Name: aws.ToString(space.AgentSpace.Name)} if !provision { step.Action = SpaceConnect + } else { + step.EnableElevated = !opts.NoElevatedActions && !space.AgentSpace.Preferences[ElevatedActionsPreference] } return step, nil @@ -622,6 +636,29 @@ func checkSpace(ctx context.Context, clients Clients, step SpaceStep) error { return nil } +// enableElevatedActions turns on elevated actions on a space. An update +// replaces all the preferences, so it sends the current ones too. +func enableElevatedActions(ctx context.Context, clients Clients, spaceID string) error { + space, err := clients.Agent.GetAgentSpace(ctx, &devopsagent.GetAgentSpaceInput{AgentSpaceId: aws.String(spaceID)}) + if err != nil { + return fmt.Errorf("unable to read agent space %s: %w", spaceID, err) + } + preferences := maps.Clone(space.AgentSpace.Preferences) + if preferences == nil { + preferences = map[string]bool{} + } + preferences[ElevatedActionsPreference] = true + _, err = clients.Agent.UpdateAgentSpace(ctx, &devopsagent.UpdateAgentSpaceInput{ + AgentSpaceId: aws.String(spaceID), + Preferences: preferences, + }) + if err != nil { + return fmt.Errorf("unable to turn on elevated actions on agent space %s: %w", spaceID, err) + } + + return nil +} + func planMCPStep(ctx context.Context, clients Clients, opts SetupOptions, spaceID string) (MCPStep, error) { step, err := planMCPAction(ctx, clients, opts, spaceID) step.Endpoint = opts.mcpEndpoint() @@ -913,11 +950,15 @@ func RunPlan(ctx context.Context, clients Clients, opts SetupOptions, plan Setup if err := checkSpace(ctx, clients, plan.Space); err != nil { return result, err } - space, err := clients.Agent.CreateAgentSpace(ctx, &devopsagent.CreateAgentSpaceInput{ + input := &devopsagent.CreateAgentSpaceInput{ Name: aws.String(plan.Space.Name), Description: aws.String(agentSpaceDescription), Tags: map[string]string{ManagedTagKey: ManagedTagValue}, - }) + } + if plan.Space.EnableElevated { + input.Preferences = map[string]bool{ElevatedActionsPreference: true} + } + space, err := clients.Agent.CreateAgentSpace(ctx, input) if err != nil { return result, fmt.Errorf("unable to create the agent space: %w", err) } @@ -926,6 +967,12 @@ func RunPlan(ctx context.Context, clients Clients, opts SetupOptions, plan Setup } else { result.AgentSpaceID = plan.Space.ID logf("Reused agent space %s (%s)", plan.Space.Name, plan.Space.ID) + if plan.Space.EnableElevated { + if err := enableElevatedActions(ctx, clients, plan.Space.ID); err != nil { + return result, err + } + logf("Turned on elevated actions on agent space %s", plan.Space.ID) + } } result.AWSAssociationID, err = FindAWSAssociation(ctx, clients, result.AgentSpaceID, accountID) From df48295b7567827611af5783b2c40b952c07e3f6 Mon Sep 17 00:00:00 2001 From: Christina Chu Date: Tue, 27 Oct 2026 15:22:48 -0700 Subject: [PATCH 2/2] feat: remove the --no-elevated-actions flag from aws-devops-agent setup A full setup now always turns on elevated actions on the agent space. Co-Authored-By: Claude Opus 5.5 --- cmd/aws_devops_agent/setup.go | 41 +++++++++++++--------------- internal/awsdevops/awsdevops_test.go | 26 ------------------ internal/awsdevops/setup.go | 6 ++-- 3 files changed, 21 insertions(+), 52 deletions(-) diff --git a/cmd/aws_devops_agent/setup.go b/cmd/aws_devops_agent/setup.go index d1b837089..3b7f96ceb 100644 --- a/cmd/aws_devops_agent/setup.go +++ b/cmd/aws_devops_agent/setup.go @@ -27,7 +27,6 @@ const ( replaceMCPTokenFlag = "replace-mcp-token" mcpServiceIDFlag = "mcp-service-id" mcpEndpointFlag = "mcp-endpoint" - noElevatedFlag = "no-elevated-actions" yesFlag = "yes" ) @@ -41,11 +40,11 @@ LaunchDarkly MCP server connection the AWS DevOps Agent needs. When the account already has agent spaces, setup asks which one to connect LaunchDarkly to. On a space that setup did not make, setup only registers the MCP server. On a space that setup made, or with --auth-flow, setup runs the -full setup. A full setup turns on elevated actions on the space, unless you -pass --no-elevated-actions. Pass --agent-space-id to pick a space without the -list, or --new-agent-space to provision another space. A new space needs a -name: pass --agent-space-name, or type one when setup asks. The run ends with -the operator app URL, where the agent is used. +full setup. A full setup turns on elevated actions on the space. Pass +--agent-space-id to pick a space without the list, or --new-agent-space to +provision another space. A new space needs a name: pass --agent-space-name, +or type one when setup asks. The run ends with the operator app URL, where +the agent is used. Each agent space gets its own LaunchDarkly MCP server registration, so each space can use a different token. The MCP server is connected with @@ -74,7 +73,6 @@ for --access-token.`, cmd.Flags().String(idpClientSecretFlag, "", "OIDC client secret, required when --auth-flow=idp") cmd.Flags().Bool(replaceMCPTokenFlag, false, "Give the agent space a new LaunchDarkly MCP server with the token passed with --access-token. Other agent spaces keep their server") cmd.Flags().String(mcpServiceIDFlag, "", "Registered MCP server to connect, instead of the server of the agent space") - cmd.Flags().Bool(noElevatedFlag, false, "Do not turn on elevated actions on the agent space. Elevated actions let the agent change AWS resources") cmd.Flags().String(mcpEndpointFlag, "", "MCP endpoint to register. Setup reuses only a server at this endpoint. Defaults to "+awsdevops.MCPServerEndpoint) cmd.Flags().Bool(yesFlag, false, "Ask no questions and accept every step") @@ -671,21 +669,20 @@ func askToken(cmd *cobra.Command, baseURI string) (string, error) { func setupOptions(cmd *cobra.Command) (awsdevops.SetupOptions, error) { opts := awsdevops.SetupOptions{ - AgentSpaceID: mustString(cmd, agentSpaceIDFlag), - AgentSpaceName: mustString(cmd, agentSpaceNameFlag), - AuthFlow: strings.ToLower(mustString(cmd, authFlowFlag)), - AuthFlowSet: cmd.Flags().Changed(authFlowFlag), - IdcInstanceARN: mustString(cmd, idcInstanceARNFlag), - IssuerURL: mustString(cmd, issuerURLFlag), - IdpClientID: mustString(cmd, idpClientIDFlag), - IdpClientSecret: mustString(cmd, idpClientSecretFlag), - NewAgentSpace: mustBool(cmd, newAgentSpaceFlag), - NoElevatedActions: mustBool(cmd, noElevatedFlag), - LDBaseURI: viper.GetString(cliflags.BaseURIFlag), - LDAccessToken: viper.GetString(cliflags.AccessTokenFlag), - ReplaceMCPToken: mustBool(cmd, replaceMCPTokenFlag), - MCPServiceID: mustString(cmd, mcpServiceIDFlag), - MCPEndpoint: mustString(cmd, mcpEndpointFlag), + AgentSpaceID: mustString(cmd, agentSpaceIDFlag), + AgentSpaceName: mustString(cmd, agentSpaceNameFlag), + AuthFlow: strings.ToLower(mustString(cmd, authFlowFlag)), + AuthFlowSet: cmd.Flags().Changed(authFlowFlag), + IdcInstanceARN: mustString(cmd, idcInstanceARNFlag), + IssuerURL: mustString(cmd, issuerURLFlag), + IdpClientID: mustString(cmd, idpClientIDFlag), + IdpClientSecret: mustString(cmd, idpClientSecretFlag), + NewAgentSpace: mustBool(cmd, newAgentSpaceFlag), + LDBaseURI: viper.GetString(cliflags.BaseURIFlag), + LDAccessToken: viper.GetString(cliflags.AccessTokenFlag), + ReplaceMCPToken: mustBool(cmd, replaceMCPTokenFlag), + MCPServiceID: mustString(cmd, mcpServiceIDFlag), + MCPEndpoint: mustString(cmd, mcpEndpointFlag), } idcSet := opts.IdcInstanceARN != "" diff --git a/internal/awsdevops/awsdevops_test.go b/internal/awsdevops/awsdevops_test.go index 7fa01410b..8882e8d11 100644 --- a/internal/awsdevops/awsdevops_test.go +++ b/internal/awsdevops/awsdevops_test.go @@ -975,32 +975,6 @@ func TestSetupLeavesASpaceWithElevatedActionsUnchanged(t *testing.T) { assert.NotContains(t, agent.calls, "UpdateAgentSpace") } -func TestSetupWithNoElevatedActionsKeepsThePreference(t *testing.T) { - agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ - AgentSpaceId: aws.String("space-existing"), - Name: aws.String("launchdarkly"), - }}} - - _, err := awsdevops.Setup(context.Background(), newTestClients(agent, newFakeIAM()), awsdevops.SetupOptions{ - AgentSpaceName: "launchdarkly", - AuthFlow: "iam", - NoElevatedActions: true, - }) - require.NoError(t, err) - assert.NotContains(t, agent.calls, "UpdateAgentSpace") - - created := &fakeAgent{} - _, err = awsdevops.Setup(context.Background(), newTestClients(created, newFakeIAM()), awsdevops.SetupOptions{ - AgentSpaceName: "fresh", - NewAgentSpace: true, - AuthFlow: "iam", - LDAccessToken: "api-token", - NoElevatedActions: true, - }) - require.NoError(t, err) - assert.Nil(t, created.createdPreferences) -} - func TestPlanSetupConnectLeavesElevatedActionsUnchanged(t *testing.T) { agent := &fakeAgent{agentSpaces: []agenttypes.AgentSpace{{ AgentSpaceId: aws.String("space-existing"), diff --git a/internal/awsdevops/setup.go b/internal/awsdevops/setup.go index 4dd87d5b8..bfbc36515 100644 --- a/internal/awsdevops/setup.go +++ b/internal/awsdevops/setup.go @@ -98,8 +98,6 @@ type SetupOptions struct { AgentSpaceID string AgentSpaceName string NewAgentSpace bool - // NoElevatedActions keeps the elevated actions preference of the space. - NoElevatedActions bool AuthFlow string // AuthFlowSet: the user passed --auth-flow. @@ -593,7 +591,7 @@ func planAgentSpace(ctx context.Context, clients Clients, opts SetupOptions, pro return SpaceStep{}, errors.New("a new agent space needs a name. Pass --agent-space-name") } if id == "" { - return SpaceStep{Action: SpaceCreate, Name: opts.AgentSpaceName, EnableElevated: !opts.NoElevatedActions}, nil + return SpaceStep{Action: SpaceCreate, Name: opts.AgentSpaceName, EnableElevated: true}, nil } space, err := clients.Agent.GetAgentSpace(ctx, &devopsagent.GetAgentSpaceInput{AgentSpaceId: aws.String(id)}) @@ -604,7 +602,7 @@ func planAgentSpace(ctx context.Context, clients Clients, opts SetupOptions, pro if !provision { step.Action = SpaceConnect } else { - step.EnableElevated = !opts.NoElevatedActions && !space.AgentSpace.Preferences[ElevatedActionsPreference] + step.EnableElevated = !space.AgentSpace.Preferences[ElevatedActionsPreference] } return step, nil