From 704ee2e0a4e7976728045a7269cd1b2e8d58a9da Mon Sep 17 00:00:00 2001 From: Marcin Owsiany Date: Wed, 18 Feb 2026 12:34:01 +0100 Subject: [PATCH] chore: use an enum for component --- cmd/deploy.go | 39 +++++++++--------- cmd/teardown.go | 11 ++--- internal/component/component.go | 71 +++++++++++++++++++++++++++++++++ internal/deployer/deployer.go | 53 +++++++++--------------- 4 files changed, 114 insertions(+), 60 deletions(-) create mode 100644 internal/component/component.go diff --git a/cmd/deploy.go b/cmd/deploy.go index d1216b02..dfd62fe1 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -8,6 +8,7 @@ import ( "time" "github.com/spf13/cobra" + "github.com/stackrox/roxie/internal/component" "github.com/stackrox/roxie/internal/deployer" "github.com/stackrox/roxie/internal/env" "github.com/stackrox/roxie/internal/helpers" @@ -61,16 +62,16 @@ func runDeploy(cmd *cobra.Command, args []string) error { log.Dim("Running without a controlling terminal.") } - component := "both" - if len(args) > 0 { - component = args[0] + components, err := component.FromArgs(args) + if err != nil { + return err } - if component == "operator" && helm { + if components.IncludesOperatorExplicitly() && helm { return errors.New("cannot use --helm flag with 'operator' component") } - if (component == "central" || component == "both") && os.Getenv("ROXIE_SHELL") != "" { + if components.IncludesCentral() && os.Getenv("ROXIE_SHELL") != "" { return errors.New("already in a roxie sub-shell (ROXIE_SHELL environment variable is set), please exit the shell and try again") } @@ -139,12 +140,11 @@ func runDeploy(cmd *cobra.Command, args []string) error { if overrideFile != "" { var err error - switch component { - case "both", "all": + if components.IncludesBothCentralAndSensor() { err = d.SetCombinedOverrideFile(overrideFile) - case "central": + } else if components.IncludesCentral() { err = d.SetCentralOverrideFile(overrideFile) - case "secured-cluster": + } else if components.IncludesSensor() { err = d.SetSecuredClusterOverrideFile(overrideFile) } if err != nil { @@ -154,12 +154,11 @@ func runDeploy(cmd *cobra.Command, args []string) error { if len(overrideSetExpressions) > 0 { var err error - switch component { - case "both", "all": + if components.IncludesBothCentralAndSensor() { err = d.SetCombinedOverrideSetExpressions(overrideSetExpressions) - case "central": + } else if components.IncludesCentral() { err = d.SetCentralOverrideSetExpressions(overrideSetExpressions) - case "secured-cluster": + } else if components.IncludesSensor() { err = d.SetSecuredClusterOverrideSetExpressions(overrideSetExpressions) } if err != nil { @@ -167,13 +166,11 @@ func runDeploy(cmd *cobra.Command, args []string) error { } } - switch component { - case "central", "both", "all": + if components.IncludesCentral() { d.PrintCentralDeploymentSummary() - case "secured-cluster", "sensor": + } + if components.IncludesSensor() { d.PrintSecuredClusterDeploymentSummary() - case "operator": - // No deployment summary needed for operator-only deployment } if envrc != "" { @@ -230,18 +227,18 @@ func runDeploy(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute) defer cancel() - if err := d.Deploy(ctx, component, resolvedResources, exposure); err != nil { + if err := d.Deploy(ctx, components, resolvedResources, exposure); err != nil { return fmt.Errorf("deployment failed: %w", err) } log.Success("🎉 Deployment complete!") // If Central was deployed, wait for it to be ready before entering subshell - if component == "central" || component == "both" || component == "all" { + if components.IncludesCentral() { d.WaitForCentral(5 * time.Minute) } - if (component == "central" || component == "both") && envrc == "" { + if components.IncludesCentral() && envrc == "" { if err := spawnSubshell(d, log); err != nil { return fmt.Errorf("failed to spawn subshell: %w", err) } diff --git a/cmd/teardown.go b/cmd/teardown.go index 7e7fb060..9d480028 100644 --- a/cmd/teardown.go +++ b/cmd/teardown.go @@ -6,6 +6,7 @@ import ( "time" "github.com/spf13/cobra" + "github.com/stackrox/roxie/internal/component" "github.com/stackrox/roxie/internal/deployer" "github.com/stackrox/roxie/internal/env" "github.com/stackrox/roxie/internal/logger" @@ -34,12 +35,12 @@ func runTeardown(cmd *cobra.Command, args []string) error { return err } - component := "both" - if len(args) > 0 { - component = args[0] + components, err := component.FromArgs(args) + if err != nil { + return err } - log.Infof("Tearing down %s", component) + log.Infof("Tearing down %s", components) d, err := deployer.New(log) if err != nil { @@ -51,7 +52,7 @@ func runTeardown(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute) defer cancel() - if err := d.Teardown(ctx, component); err != nil { + if err := d.Teardown(ctx, components); err != nil { return fmt.Errorf("teardown failed: %w", err) } diff --git a/internal/component/component.go b/internal/component/component.go new file mode 100644 index 00000000..3fe6ebdf --- /dev/null +++ b/internal/component/component.go @@ -0,0 +1,71 @@ +package component + +import "fmt" + +type Component int + +const ( + All Component = iota + Central + SecuredCluster + Operator +) + +func FromArgs(args []string) (Component, error) { + if len(args) > 0 { + switch args[0] { + case "both", "all": + return All, nil + case "central": + return Central, nil + case "secured-cluster", "sensor": + return SecuredCluster, nil + case "operator": + return Operator, nil + default: + return All, fmt.Errorf("unknown component: %s", args[0]) + } + } + return All, nil +} + +func (c Component) String() string { + switch c { + case All: + return "Central and Secured Cluster" + case Central: + return "Central" + case SecuredCluster: + return "Secured Cluster" + case Operator: + return "Operator" + default: + return fmt.Sprintf("Unknown(%d)", c) + } +} + +func (c Component) IncludesCentral() bool { + if c == SecuredCluster || c == Operator { + return false + } + return true +} + +func (c Component) IncludesSensor() bool { + if c == Central || c == Operator { + return false + } + return true +} + +func (c Component) IncludesOperator() bool { + return c == Operator || c == All +} + +func (c Component) IncludesOperatorExplicitly() bool { + return c == Operator +} + +func (c Component) IncludesBothCentralAndSensor() bool { + return c == Central || c == SecuredCluster || c == All +} diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index adece06e..e1e56b2c 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -14,6 +14,7 @@ import ( "gopkg.in/yaml.v3" "github.com/stackrox/roxie/internal/clusterdefaults" + "github.com/stackrox/roxie/internal/component" "github.com/stackrox/roxie/internal/dockerauth" "github.com/stackrox/roxie/internal/env" "github.com/stackrox/roxie/internal/helpers" @@ -521,22 +522,7 @@ func (d *Deployer) getClusterResourceKinds() (map[string]struct{}, error) { return kinds, nil } -func formatComponentName(component string) string { - switch component { - case "both", "all": - return "Central and Secured Cluster" - case "secured-cluster", "sensor": - return "Secured Cluster" - case "central": - return "Central" - case "operator": - return "Operator" - default: - return component - } -} - -func (d *Deployer) Deploy(ctx context.Context, component, resources, exposure string) error { +func (d *Deployer) Deploy(ctx context.Context, components component.Component, resources, exposure string) error { adjustedResources, adjustedExposure, adjustedPortForward := d.clusterDefaults.ApplyConvenienceDefaults( d.kubeContext, resources, @@ -557,23 +543,22 @@ func (d *Deployer) Deploy(ctx context.Context, component, resources, exposure st } } - d.logger.Infof("Initiating deployment of %s", formatComponentName(component)) + d.logger.Infof("Initiating deployment of %s", components) - switch component { - case "operator": + if components.IncludesOperator() { return d.deployOperatorOnly(ctx) - case "central": - return d.deployCentral(ctx, resources, exposure) - case "secured-cluster", "sensor": - return d.deploySecuredCluster(ctx, resources) - case "both", "all": + } + if components.IncludesCentral() { if err := d.deployCentral(ctx, resources, exposure); err != nil { return fmt.Errorf("failed to deploy central: %w", err) } - return d.deploySecuredCluster(ctx, resources) - default: - return fmt.Errorf("unknown component: %s", component) } + if components.IncludesSensor() { + if err := d.deploySecuredCluster(ctx, resources); err != nil { + return fmt.Errorf("failed to deploy secured cluster: %w", err) + } + } + return nil } // prepareCredentials prepares and verifies Docker credentials early to fail fast. @@ -641,21 +626,21 @@ func (d *Deployer) deploySecuredCluster(ctx context.Context, resources string) e return d.deploySecuredClusterOperator(ctx, resources) } -func (d *Deployer) Teardown(ctx context.Context, component string) error { - d.logger.Infof("Starting teardown of %s", component) +func (d *Deployer) Teardown(ctx context.Context, components component.Component) error { + d.logger.Infof("Starting teardown of %s", components) - switch component { - case "central": + switch components { + case component.Central: return d.teardownCentral(ctx) - case "secured-cluster", "sensor": + case component.SecuredCluster: return d.teardownSecuredCluster(ctx) - case "both", "all": + case component.All: if err := d.teardownSecuredCluster(ctx); err != nil { d.logger.Warningf("Error tearing down secured cluster: %v", err) } return d.teardownCentral(ctx) default: - return fmt.Errorf("unknown component: %s", component) + return fmt.Errorf("unknown component: %s", components) } }