sg/msp: filter generated environments by category (#62131)

Part of https://github.com/sourcegraph/managed-services/issues/599

See https://github.com/sourcegraph/managed-services/pull/1288 for how this mechanism will be used.

## Test plan

```sh
sg msp generate -all -category=test
```

![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/d27c5df5-6d13-43fa-96c2-5523da24693a)
This commit is contained in:
Robert Lin 2024-04-24 09:44:16 -07:00 committed by GitHub
parent 2ecd2d1f00
commit 3623ecb2cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 9 deletions

View File

@ -32,8 +32,9 @@ func (c CDKTF) OutputDir() string {
// configured.
func (c CDKTF) Synthesize() error {
// Forcibly shut down the JSII runtime post-Synth to make sure that we don't
// get bizarre side-effects from multiple apps being rendered.
defer jsiiruntime.Close()
// get bizarre side-effects from multiple apps being rendered. We use a panic
// catcher to discard useless panics from the library.
defer (&panics.Catcher{}).Try(jsiiruntime.Close)
// CDKTF is prone to panics for no good reason, so make a best-effort
// attempt to capture them.

View File

@ -155,6 +155,8 @@ func syncEnvironmentWorkspaces(c *cli.Context, tfc *terraformcloud.Client, servi
type generateTerraformOptions struct {
// targetEnv generates the specified env only, otherwise generates all
targetEnv string
// targetCategory generates the specified category only
targetCategory spec.EnvironmentCategory
// stableGenerate disables updating of any values that are evaluated at
// generation time
stableGenerate bool
@ -178,8 +180,16 @@ func generateTerraform(service *spec.Spec, opts generateTerraformOptions) error
for _, env := range envs {
env := env
pending := std.Out.Pending(output.Styledf(output.StylePending,
"[%s] Preparing Terraform for environment %q", serviceID, env.ID))
if opts.targetCategory != "" && env.Category != opts.targetCategory {
// Quietly skip environments that don't match specified category
std.Out.WriteLine(output.StyleSuggestion.Linef(
"[%s] Skipping non-%q environment %q (category %q)",
serviceID, opts.targetCategory, env.ID, env.Category))
continue
}
pending := std.Out.Pending(output.StylePending.Linef(
"[%s] Preparing Terraform for %q environment %q", serviceID, env.Category, env.ID))
renderer := managedservicesplatform.Renderer{
OutputDir: filepath.Join(filepath.Dir(serviceSpecPath), "terraform", env.ID),
StableGenerate: opts.stableGenerate,
@ -204,8 +214,8 @@ func generateTerraform(service *spec.Spec, opts generateTerraformOptions) error
return err
}
pending.Updatef("[%s] Generating Terraform assets in %q for environment %q...",
serviceID, renderer.OutputDir, env.ID)
pending.Updatef("[%s] Generating Terraform assets in %q for %q environment %q...",
serviceID, renderer.OutputDir, env.Category, env.ID)
if err := cdktf.Synthesize(); err != nil {
return err
}

View File

@ -272,10 +272,15 @@ Supports completions on services and environments.`,
UsageText: `
# generate single env for a single service
sg msp generate <service> <env>
# generate all envs for a single service
sg msp generate -all <service>
# generate all envs across all services
sg msp generate -all
# generate all test envs across all services
sg msp generate -all -category=test
`,
Before: msprepo.UseManagedServicesRepo,
Flags: []cli.Flag{
@ -284,6 +289,10 @@ sg msp generate -all
Usage: "Generate infrastructure stacks for all services, or all envs for a service if service ID is provided",
Value: false,
},
&cli.StringFlag{
Name: "category",
Usage: "Filter generated environments by category (one of 'test', 'internal', 'external') - must be used with '-all'",
},
&cli.BoolFlag{
Name: "stable",
Usage: "Configure updating of any values that are evaluated at generation time",
@ -293,14 +302,24 @@ sg msp generate -all
BashComplete: msprepo.ServicesAndEnvironmentsCompletion(),
Action: func(c *cli.Context) error {
var (
generateAll = c.Bool("all")
stableGenerate = c.Bool("stable")
generateAll = c.Bool("all")
generateCategory = spec.EnvironmentCategory(c.String("category"))
stableGenerate = c.Bool("stable")
)
if stableGenerate {
std.Out.WriteSuggestionf("Using stable generate - tfvars will not be updated.")
}
if generateCategory != "" {
if !generateAll {
return errors.New("'-category' must be used with '-all'")
}
if err := generateCategory.Validate(); err != nil {
return errors.Wrap(err, "invalid value for '-category'")
}
}
// Generate a specific service environment if '-all' is not provided
if !generateAll {
std.Out.WriteNoticef("Generating a specific service environment...")
@ -323,6 +342,7 @@ sg msp generate -all
}
return generateTerraform(svc, generateTerraformOptions{
stableGenerate: stableGenerate,
targetCategory: generateCategory,
})
}
@ -341,6 +361,7 @@ sg msp generate -all
}
if err := generateTerraform(s, generateTerraformOptions{
stableGenerate: stableGenerate,
targetCategory: generateCategory,
}); err != nil {
return errors.Wrap(err, serviceID)
}

View File

@ -45,7 +45,7 @@ func Emoji(emoji string, s string) FancyLine {
return Line(emoji, StyleReset, s)
}
// Emoji creates a new FancyLine with an emoji prefix and style.
// Emoji creates a new FancyLine with an emoji prefix and format string.
func Emojif(emoji string, s string, a ...any) FancyLine {
return Linef(emoji, StyleReset, s, a...)
}

View File

@ -9,6 +9,14 @@ type Style struct{ code string }
func (s Style) String() string { return s.code }
// Line returns a FancyLine using this style as an alias for using output.Styledf(...)
func (s Style) Line(format string) FancyLine { return Styled(s, format) }
// Linef returns a FancyLine using this style as an alias for using output.Styledf(...)
func (s Style) Linef(format string, args ...interface{}) FancyLine {
return Styledf(s, format, args...)
}
func CombineStyles(styles ...Style) Style {
sb := strings.Builder{}
for _, s := range styles {