diff --git a/dev/managedservicesplatform/terraformcloud/terraformcloud.go b/dev/managedservicesplatform/terraformcloud/terraformcloud.go index 90915dcb51e..bd2d8f23528 100644 --- a/dev/managedservicesplatform/terraformcloud/terraformcloud.go +++ b/dev/managedservicesplatform/terraformcloud/terraformcloud.go @@ -52,6 +52,9 @@ type WorkspaceRunMode string const ( WorkspaceRunModeVCS WorkspaceRunMode = "vcs" WorkspaceRunModeCLI WorkspaceRunMode = "cli" + // WorkspaceRunModeIgnore is used to indicate that the workspace's run mode + // should not be modified. + WorkspaceRunModeIgnore WorkspaceRunMode = "ignore" ) type WorkspaceConfig struct { @@ -266,6 +269,9 @@ func (c *Client) SyncWorkspaces(ctx context.Context, svc spec.ServiceSpec, env s // to TFC, hence we need to remove all VCS and working directory override wantWorkspaceOptions.VCSRepo = nil wantWorkspaceOptions.WorkingDirectory = nil + case WorkspaceRunModeIgnore: + // We will apply existing configuration later before the + // 'Workspaces.Update' operation default: return nil, errors.Errorf("invalid WorkspaceRunModeVCS %q", c.workspaceConfig.RunMode) } @@ -281,6 +287,11 @@ func (c *Client) SyncWorkspaces(ctx context.Context, svc spec.ServiceSpec, env s return nil, errors.Wrap(err, "failed to check if workspace exists") } + if c.workspaceConfig.RunMode == WorkspaceRunModeIgnore { + // Can't ignore a configuration that doesn't exist yet! + return nil, errors.New("cannot create workspace in WorkspaceRunModeIgnore") + } + createdWorkspace, err := c.client.Workspaces.Create(ctx, c.org, wantWorkspaceOptions.AsCreate(wantWorkspaceTags)) if err != nil { @@ -296,6 +307,19 @@ func (c *Client) SyncWorkspaces(ctx context.Context, svc spec.ServiceSpec, env s Name: existingWorkspace.Name, }) + // Apply existing config relevant to run mode explicitly + if c.workspaceConfig.RunMode == WorkspaceRunModeIgnore { + if existingWorkspace.VCSRepo != nil { + wantWorkspaceOptions.VCSRepo = &tfe.VCSRepoOptions{ + OAuthTokenID: &existingWorkspace.VCSRepo.OAuthTokenID, + Identifier: &existingWorkspace.VCSRepo.Identifier, + Branch: &existingWorkspace.VCSRepo.Branch, + } + } + wantWorkspaceOptions.WorkingDirectory = &existingWorkspace.WorkingDirectory + wantWorkspaceOptions.TriggerPrefixes = existingWorkspace.TriggerPrefixes + } + // VCSRepo must be removed by explicitly using the API - update // doesn't remove it - if we want to remove the connection. if existingWorkspace.VCSRepo != nil && wantWorkspaceOptions.VCSRepo == nil { diff --git a/dev/sg/msp/sg_msp.go b/dev/sg/msp/sg_msp.go index 3643716a1c4..1850b7e8d72 100644 --- a/dev/sg/msp/sg_msp.go +++ b/dev/sg/msp/sg_msp.go @@ -841,7 +841,7 @@ This command supports completions on services and environments. }, &cli.StringFlag{ Name: "workspace-run-mode", - Usage: "One of 'vcs', 'cli'", + Usage: "One of 'vcs', 'cli', or 'ignore' (to respect existing configuration)", Value: "vcs", }, &cli.BoolFlag{ @@ -871,9 +871,10 @@ This command supports completions on services and environments. return errors.Wrap(err, "get TFC OAuth client ID") } + runMode := terraformcloud.WorkspaceRunMode(c.String("workspace-run-mode")) tfcClient, err := terraformcloud.NewClient(tfcAccessToken, tfcOAuthClient, terraformcloud.WorkspaceConfig{ - RunMode: terraformcloud.WorkspaceRunMode(c.String("workspace-run-mode")), + RunMode: runMode, }) if err != nil { return errors.Wrap(err, "init Terraform Cloud client") @@ -899,7 +900,15 @@ This command supports completions on services and environments. return errors.New("cannot delete workspaces for all services") } - std.Out.Promptf("Syncing all environments for all services - are you sure? (y/N) ") + confirmAction := "Syncing all environments for all services" + if runMode != terraformcloud.WorkspaceRunModeIgnore { + // This action may override custom run mode + // configurations, which may unexpectedly deploy + // new changes + confirmAction = fmt.Sprintf("%s, including setting ALL workspaces to use run mode %q (use '-workspace-run-mode=ignore' to respect the existing run mode)", + confirmAction, runMode) + } + std.Out.Promptf("%s - are you sure? (y/N) ", confirmAction) var input string if _, err := fmt.Scan(&input); err != nil { return err