From 98f41feb461e3a7e2ac01d3c75205f053d0f8fde Mon Sep 17 00:00:00 2001 From: Moritz Clasmeier Date: Fri, 17 Apr 2026 10:11:52 +0200 Subject: [PATCH 1/2] Use resource constants (they were forgotten and only used for Helm) --- internal/deployer/deploy_via_operator.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/deployer/deploy_via_operator.go b/internal/deployer/deploy_via_operator.go index 4091112e..a8161c69 100644 --- a/internal/deployer/deploy_via_operator.go +++ b/internal/deployer/deploy_via_operator.go @@ -297,6 +297,10 @@ func (d *Deployer) getCentralResourcesOperator(resourcesName string) map[string] "analyzer": map[string]interface{}{ "scaling": noScaling, }, + "resources": centralScannerResourcesSmall, + "db": map[string]interface{}{ + "resources": centralScannerDbResourcesSmall, + }, }, "scannerV4": map[string]interface{}{ "db": map[string]interface{}{ @@ -327,6 +331,10 @@ func (d *Deployer) getCentralResourcesOperator(resourcesName string) map[string] "analyzer": map[string]interface{}{ "scaling": noScaling, }, + "resources": centralScannerResourcesMedium, + "db": map[string]interface{}{ + "resources": centralScannerDbResourcesMedium, + }, }, "scannerV4": map[string]interface{}{ "db": map[string]interface{}{ From dc8fc3b4aca54d058028dacd7a036a604f412896 Mon Sep 17 00:00:00 2001 From: Moritz Clasmeier Date: Fri, 17 Apr 2026 10:13:39 +0200 Subject: [PATCH 2/2] Remove Helm support --- Dockerfile | 1 - README.md | 9 +- cmd/deploy.go | 24 - cmd/main.go | 3 +- cmd/teardown.go | 2 - flake.nix | 4 - internal/deployer/deploy_via_helm.go | 537 ----------------------- internal/deployer/deploy_via_operator.go | 1 - internal/deployer/deployer.go | 36 +- tests/e2e/e2e_test.go | 33 -- 10 files changed, 7 insertions(+), 643 deletions(-) delete mode 100644 internal/deployer/deploy_via_helm.go diff --git a/Dockerfile b/Dockerfile index 1abe7850..7f462f5d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -98,7 +98,6 @@ LABEL maintainer="StackRox" \ io.k8s.display-name="roxie ACS Deployment Tool" # Install required tools via microdnf -# kubectl, helm are available in RHEL repos # Note: UBI minimal comes with curl pre-installed, which is sufficient for our needs RUN microdnf install -y \ # Core utilities diff --git a/README.md b/README.md index b76a2f8c..fd2b6a39 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,12 @@ roxie has been authored with significant AI contributions. - Automated waiting for readiness and loadbalancer availability. - No fiddling with API endpoints: detects and wires endpoints automatically. - No fiddling with init bundles or CRS: roxie generates and handles these bits for you. -- Operator by default: deploys the ACS Operator without requiring OpenShift/OLM. Helm is also supported. +- Deploys the ACS Operator without requiring OpenShift/OLM. - Ability to replace operator versions (up- and downgrading). - Automated fast ACS teardowns. - Handles Quay image pull secrets automatically. - Verifies image existence before attempting deployment. -Note: Helm charts are currently also supported: use `--helm` to deploy Central and Secured Cluster via Helm. Only -use this in case you have very specific requirements which force you to use the Helm charts directly. -One example would be working on the Helm charts and needing to test them independently of the ACS operator. -Support for Helm charts might be dropped in the future. - ## Quick start ### Option 1: Deploying using image (Recommended for non-developers) @@ -120,4 +115,4 @@ docker related targets. ## Testing (E2E) -The E2E suite expects a valid `kubectl` context. \ No newline at end of file +The E2E suite expects a valid `kubectl` context. diff --git a/cmd/deploy.go b/cmd/deploy.go index 6b41d009..3343c330 100644 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -31,8 +31,6 @@ Examples: RunE: runDeploy, } - cmd.Flags().BoolVar(&helm, "helm", false, "Deploy using Helm charts instead of operator") - _ = cmd.Flags().MarkHidden("helm") cmd.Flags().BoolVar(&olm, "olm", false, "Deploy operator via OLM (requires OLM installed)") cmd.Flags().BoolVar(&konflux, "konflux", false, "Use Konflux images") cmd.Flags().BoolVar(&deployOperator, "deploy-operator", true, "Deploy and check operator (set to false to skip operator deployment/checks)") @@ -54,15 +52,6 @@ Examples: } func runDeploy(cmd *cobra.Command, args []string) error { - // Validate flag combinations early, before env initialization - if helm && olm { - return errors.New("cannot use both --helm and --olm flags together") - } - - if helm && len(featureFlags) > 0 { - return errors.New("--features flag is not supported with --helm (feature flags only work with operator-based deployments)") - } - log := logger.New() if err := env.Initialize(log); err != nil { return err @@ -79,10 +68,6 @@ func runDeploy(cmd *cobra.Command, args []string) error { return err } - if components.IncludesOperatorExplicitly() && helm { - return errors.New("cannot use --helm flag with 'operator' component") - } - 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") } @@ -122,9 +107,6 @@ func runDeploy(cmd *cobra.Command, args []string) error { } if konflux { - if helm { - return errors.New("cannot use both --helm and --konflux flags together (Konflux requires operator-based deployment)") - } if olm { return errors.New("cannot use both --olm and --konflux flags together (not currently implemented)") } @@ -182,12 +164,6 @@ func runDeploy(cmd *cobra.Command, args []string) error { d.SetEnvrcFile(envrc) } - if helm { - if err := d.SetUseHelm(true); err != nil { - return err - } - } - if olm { if err := d.SetUseOLM(true); err != nil { return err diff --git a/cmd/main.go b/cmd/main.go index d64f90f6..bb576216 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -11,7 +11,6 @@ var ( // Global flags verbose bool earlyReadiness bool - helm bool olm bool konflux bool deployOperator bool @@ -48,7 +47,7 @@ Red Hat Advanced Cluster Security (ACS) on any Kubernetes/OpenShift cluster.`, } func init() { - rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output (show CRs and Helm values)") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output (show CRs)") rootCmd.PersistentFlags().BoolVar(&earlyReadiness, "early-readiness", true, "Only wait for essential workloads (central/sensor) to be ready") rootCmd.AddCommand(newDeployCmd()) rootCmd.AddCommand(newTeardownCmd()) diff --git a/cmd/teardown.go b/cmd/teardown.go index 9d480028..015d8cdf 100644 --- a/cmd/teardown.go +++ b/cmd/teardown.go @@ -22,8 +22,6 @@ func newTeardownCmd() *cobra.Command { RunE: runTeardown, } - cmd.Flags().BoolVar(&helm, "helm", false, "Force teardown of Helm deployment") - _ = cmd.Flags().MarkHidden("helm") cmd.Flags().BoolVar(&singleNamespace, "single-namespace", false, "Deploy all components in a single namespace ('stackrox' by default)") return cmd diff --git a/flake.nix b/flake.nix index 8cc1238c..d3b9feac 100644 --- a/flake.nix +++ b/flake.nix @@ -79,7 +79,6 @@ # Essential Kubernetes tools (lightweight) kubectl - kubernetes-helm # Optional: Kubernetes utilities (lightweight) k9s @@ -92,7 +91,6 @@ echo "Available tools:" echo " - roxie ($(roxie version))" echo " - kubectl ($(kubectl version --client --short 2>/dev/null || echo 'not configured'))" - echo " - helm ($(helm version --short 2>/dev/null || echo 'unknown'))" echo " - Go $(go version | cut -d' ' -f3)" echo "" echo "💡 For full set of pre-installed tooling use:" @@ -116,7 +114,6 @@ # Kubernetes tools kubectl - kubernetes-helm k9s stern @@ -133,7 +130,6 @@ echo "Available tools:" echo " - roxie ($(roxie version))" echo " - kubectl ($(kubectl version --client --short 2>/dev/null || echo 'not configured'))" - echo " - helm ($(helm version --short 2>/dev/null || echo 'unknown'))" echo " - podman ($(podman --version | head -n1))" echo " - haproxy ($(haproxy -v | head -n1))" echo "" diff --git a/internal/deployer/deploy_via_helm.go b/internal/deployer/deploy_via_helm.go deleted file mode 100644 index 2319427f..00000000 --- a/internal/deployer/deploy_via_helm.go +++ /dev/null @@ -1,537 +0,0 @@ -package deployer - -import ( - "bytes" - "context" - "errors" - "fmt" - "os" - "os/exec" - "strings" - - "gopkg.in/yaml.v3" - - "github.com/stackrox/roxie/internal/env" - "github.com/stackrox/roxie/internal/helpers" -) - -// deployCentralHelm deploys Central using Helm charts -func (d *Deployer) deployCentralHelm(ctx context.Context, resources, exposure string) error { - d.logger.Info("🚀 Deploying Central via Helm...") - - chartDir, err := os.MkdirTemp("", "central-services-chart-") - if err != nil { - return fmt.Errorf("failed to create temp dir: %w", err) - } - defer d.cleanupTempDir(chartDir, "central chart directory") - - d.logger.Infof("Chart directory: %s", chartDir) - - if err := d.generateCentralChart(ctx, chartDir); err != nil { - return fmt.Errorf("failed to generate central chart: %w", err) - } - - helmValues, err := d.createCentralValues(resources, exposure) - if err != nil { - return fmt.Errorf("failed to create Helm values: %w", err) - } - - helmValuesYamlBytes, err := yaml.Marshal(helmValues) - if err != nil { - return fmt.Errorf("failed to marshal Helm values: %w", err) - } - helmValuesYaml := string(helmValuesYamlBytes) - - valuesFile, err := os.CreateTemp("", "central-values-*.yaml") - if err != nil { - return fmt.Errorf("failed to create values file: %w", err) - } - defer os.Remove(valuesFile.Name()) - defer valuesFile.Close() - - if _, err := valuesFile.WriteString(helmValuesYaml); err != nil { - return fmt.Errorf("failed to write values file: %w", err) - } - valuesFile.Close() - - if d.verbose { - if env.RunningInteractively { - d.logger.Dim("Central values YAML:") - d.logger.Dim(helmValuesYaml) - } else { - d.logger.Dim("Skipping emitting Central values in non-interactive mode, because it could leak confidential information") - } - } - - if err := d.verifyHelmChartImages(ctx, chartDir, valuesFile.Name()); err != nil { - return fmt.Errorf("image verification failed: %w", err) - } - - // Delete CRDs if they exist (Helm will recreate them) - d.deleteCRDs(ctx) - - if err := d.ensureNamespaceExists(d.centralNamespace); err != nil { - return err - } - - if err := d.prepareNamespace(ctx, d.centralNamespace); err != nil { - return fmt.Errorf("failed to prepare namespace: %w", err) - } - - if err := d.installCentralHelmChart(ctx, chartDir, valuesFile.Name()); err != nil { - return fmt.Errorf("failed to install helm chart: %w", err) - } - - if err := d.waitForCentralReady(ctx, d.centralWaitTimeout); err != nil { - return fmt.Errorf("failed waiting for Central: %w", err) - } - - return d.configureCentralEndpoint(ctx, exposure) -} - -// deploySecuredClusterHelm deploys SecuredCluster using Helm charts -func (d *Deployer) deploySecuredClusterHelm(ctx context.Context, resources string) error { - d.logger.Info("🚀 Deploying SecuredCluster via Helm...") - - clusterName := generateClusterName() - - chartDir, err := os.MkdirTemp("", "secured-cluster-services-chart-") - if err != nil { - return fmt.Errorf("failed to create temp dir: %w", err) - } - defer d.cleanupTempDir(chartDir, "secured-cluster chart directory") - - d.logger.Infof("Chart directory: %s", chartDir) - - crsContent, err := d.generateCRS(ctx, clusterName) - if err != nil { - return fmt.Errorf("failed to generate CRS: %w", err) - } - - if err := d.generateSecuredClusterChart(ctx, chartDir); err != nil { - return fmt.Errorf("failed to generate secured cluster chart: %w", err) - } - - helmValues, err := d.createSecuredClusterValues(clusterName, resources) - if err != nil { - return fmt.Errorf("failed to create values YAML: %w", err) - } - - helmValuesYamlBytes, err := yaml.Marshal(helmValues) - if err != nil { - return fmt.Errorf("failed to marshal Helm values: %w", err) - } - helmValuesYaml := string(helmValuesYamlBytes) - - valuesFile, err := os.CreateTemp("", "secured-cluster-values-*.yaml") - if err != nil { - return fmt.Errorf("failed to create values file: %w", err) - } - defer os.Remove(valuesFile.Name()) - defer valuesFile.Close() - - if _, err := valuesFile.WriteString(helmValuesYaml); err != nil { - return fmt.Errorf("failed to write values file: %w", err) - } - valuesFile.Close() - - crsFile, err := os.CreateTemp("", "crs-*.yaml") - if err != nil { - return fmt.Errorf("failed to create CRS file: %w", err) - } - defer os.Remove(crsFile.Name()) - defer crsFile.Close() - - if _, err := crsFile.WriteString(crsContent); err != nil { - return fmt.Errorf("failed to write CRS file: %w", err) - } - crsFile.Close() - - if d.verbose { - if env.RunningInteractively { - d.logger.Dim("SecuredCluster values YAML:") - d.logger.Dim(helmValuesYaml) - } else { - d.logger.Dim("Skipping emitting SecuredCluster values in non-interactive mode, because it could leak confidential information") - } - } - - if err := d.ensureNamespaceExists(d.sensorNamespace); err != nil { - return err - } - - if err := d.prepareNamespace(ctx, d.sensorNamespace); err != nil { - return fmt.Errorf("failed to prepare namespace: %w", err) - } - - if err := d.installSecuredClusterHelmChart(ctx, chartDir, valuesFile.Name(), crsFile.Name()); err != nil { - return fmt.Errorf("failed to install helm chart: %w", err) - } - - if err := d.waitForSecuredClusterReady(ctx, d.securedClusterWaitTimeout); err != nil { - return fmt.Errorf("failed waiting for SecuredCluster: %w", err) - } - - d.logger.Successf("✓ SecuredCluster '%s' is ready", clusterName) - return nil -} - -// generateCentralChart generates the central-services Helm chart using roxctl -func (d *Deployer) generateCentralChart(ctx context.Context, outputDir string) error { - d.logger.Info("Generating central-services chart with roxctl...") - - _, err := d.runRoxctl(ctx, RoxctlOptions{ - Args: []string{ - "helm", "output", "central-services", - "--remove", "--debug", "--output-dir", outputDir, - }, - UseAuthentication: false, - }) - - if err != nil { - return fmt.Errorf("failed to generate central chart: %w", err) - } - - d.logger.Success("✓ Central chart generated") - return nil -} - -// generateSecuredClusterChart generates the secured-cluster-services Helm chart using roxctl -func (d *Deployer) generateSecuredClusterChart(ctx context.Context, outputDir string) error { - d.logger.Info("Generating secured-cluster-services chart with roxctl...") - - _, err := d.runRoxctl(ctx, RoxctlOptions{ - Args: []string{ - "helm", "output", "secured-cluster-services", - "--remove", "--debug", "--output-dir", outputDir, - }, - UseAuthentication: false, - }) - - if err != nil { - return fmt.Errorf("failed to generate secured cluster chart: %w", err) - } - - d.logger.Success("✓ SecuredCluster chart generated") - return nil -} - -// createCentralValuesYAML creates the Helm values YAML for Central deployment -func (d *Deployer) createCentralValues(resourcesName, exposure string) (map[string]interface{}, error) { - base := map[string]interface{}{ - "central": map[string]interface{}{ - "adminPassword": map[string]interface{}{ - "value": d.centralPassword, - }, - "exposure": d.getCentralExposureConfigHelm(exposure), - "telemetry": map[string]interface{}{ - "enabled": false, - }, - }, - "allowNonstandardNamespace": true, - } - - imageSettings := map[string]interface{}{} - if d.mainImageTag != "" { - imageSettings = map[string]interface{}{ - "central": map[string]interface{}{ - "db": map[string]interface{}{ - "image": map[string]interface{}{ - "tag": d.mainImageTag, - }, - }, - "image": map[string]interface{}{ - "tag": d.mainImageTag, - }, - }, - "scannerV4": map[string]interface{}{ - "image": map[string]interface{}{ - "tag": d.mainImageTag, - }, - "db": map[string]interface{}{ - "image": map[string]interface{}{ - "tag": d.mainImageTag, - }, - }, - }, - } - } - - resourcesOverlay := d.getCentralResourcesHelm(resourcesName) - - merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, d.centralOverrides) - - return merged, nil -} - -// createSecuredClusterValuesYAML creates the Helm values YAML for SecuredCluster deployment -func (d *Deployer) createSecuredClusterValues(clusterName, resources string) (map[string]interface{}, error) { - base := map[string]interface{}{ - "clusterName": clusterName, - "centralEndpoint": "https://central." + centralNamespace + ".svc:443", - "allowNonstandardNamespace": true, - } - - imageSettings := map[string]interface{}{} - if d.mainImageTag != "" { - imageSettings = map[string]interface{}{ - "image": map[string]interface{}{ - "main": map[string]interface{}{ - "tag": d.mainImageTag, - }, - }, - "scannerV4": map[string]interface{}{"tag": d.mainImageTag}, - "scannerV4DB": map[string]interface{}{"tag": d.mainImageTag}, - } - } - - resourcesOverlay := d.getSecuredClusterResourcesHelm(resources) - - merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, d.securedClusterOverrides) - - return merged, nil -} - -// getCentralExposureConfigHelm returns the exposure configuration for Helm -func (d *Deployer) getCentralExposureConfigHelm(exposure string) map[string]interface{} { - switch exposure { - case "loadbalancer": - return map[string]interface{}{ - "loadBalancer": map[string]interface{}{ - "enabled": true, - }, - } - case "none": - return map[string]interface{}{ - "loadBalancer": map[string]interface{}{ - "enabled": false, - }, - } - default: - return map[string]interface{}{ - "loadBalancer": map[string]interface{}{ - "enabled": true, - }, - } - } -} - -// getCentralResourcesHelm returns resource overlays for Central Helm deployment -func (d *Deployer) getCentralResourcesHelm(resourcesName string) map[string]interface{} { - switch resourcesName { - case "small": - return map[string]interface{}{ - "central": map[string]interface{}{ - "resources": centralResourcesSmall, - "db": map[string]interface{}{ - "resources": centralDbResourcesSmall, - }, - }, - "scanner": map[string]interface{}{ - "resources": centralScannerResourcesSmall, - "dbResources": centralScannerDbResourcesSmall, - }, - "scannerV4": map[string]interface{}{ - "indexer": map[string]interface{}{ - "resources": centralScannerV4IndexerResourcesSmall, - }, - "matcher": map[string]interface{}{ - "resources": centralScannerV4MatcherResourcesSmall, - }, - "db": map[string]interface{}{ - "resources": centralScannerV4DbResourcesSmall, - }, - }, - } - case "medium": - return map[string]interface{}{ - "central": map[string]interface{}{ - "resources": centralResourcesMedium, - "db": map[string]interface{}{ - "resources": centralDbResourcesMedium, - }, - }, - "scanner": map[string]interface{}{ - "resources": centralScannerResourcesMedium, - "dbResources": centralScannerDbResourcesMedium, - }, - "scannerV4": map[string]interface{}{ - "indexer": map[string]interface{}{ - "resources": centralScannerV4IndexerResourcesMedium, - }, - "matcher": map[string]interface{}{ - "resources": centralScannerV4MatcherResourcesMedium, - }, - "db": map[string]interface{}{ - "resources": centralScannerV4DbResourcesMedium, - }, - }, - } - default: - return nil - } -} - -// getSecuredClusterResourcesHelm returns resource overlays for SecuredCluster Helm deployment -func (d *Deployer) getSecuredClusterResourcesHelm(resourcesName string) map[string]interface{} { - switch resourcesName { - case "small": - return map[string]interface{}{ - "sensor": map[string]interface{}{ - "resources": securedClusterSensorResourcesSmall, - }, - "scanner": map[string]interface{}{ - "disable": true, - }, - "scannerV4": map[string]interface{}{ - "disable": true, - }, - } - case "medium": - return map[string]interface{}{ - "sensor": map[string]interface{}{ - "resources": securedClusterSensorResourcesMedium, - }, - "scanner": map[string]interface{}{ - "disable": true, - }, - "scannerV4": map[string]interface{}{ - "disable": true, - }, - } - default: - return nil - } -} - -// verifyHelmChartImages renders the Helm template and verifies that images are pullable -func (d *Deployer) verifyHelmChartImages(ctx context.Context, chartDir, valuesFile string) error { - d.logger.Info("Rendering Helm chart to verify images...") - - cmd := exec.CommandContext(ctx, "helm", "template", - "-n", d.centralNamespace, - "stackrox-central-services", - chartDir, - "-f", valuesFile) - - output, err := cmd.Output() - if err != nil { - return fmt.Errorf("failed to render helm template: %w", err) - } - - imageRefs := extractMainImageReferences(string(output)) - - if len(imageRefs) == 0 { - d.logger.Warning("No images found in rendered template") - return nil - } - - d.logger.Infof("Found %d unique image(s) to verify", len(imageRefs)) - for _, img := range imageRefs { - d.logger.Dim(fmt.Sprintf(" - %s", img)) - } - - if !d.imageCache.VerifyImagesPullable(ctx, imageRefs...) { - return errors.New("one or more images not found or not pullable") - } - - d.logger.Success("✓ All images verified") - return nil -} - -// extractMainImageReferences extracts unique image references from rendered YAML -func extractMainImageReferences(renderedYAML string) []string { - seen := make(map[string]bool) - var images []string - - lines := strings.Split(renderedYAML, "\n") - for _, line := range lines { - // Look for lines like: image: "quay.io/stackrox-io/main:4.8.2" - // TODO(#91): this assumes image names will always be quoted with `"` and there will be - // a single space between `:` and `"`, we should make this more robust. It might be - // better to parse the yaml and walk the resulting map, returning string values of - // `image` keys... - if strings.Contains(line, `image: "`) { - parts := strings.SplitN(line, `image: "`, 2) - if len(parts) == 2 { - imageParts := strings.SplitN(parts[1], `"`, 2) - if len(imageParts) > 0 { - imageRef := imageParts[0] - // Only include images with "/main:" tag - if strings.Contains(imageRef, "/main:") && !seen[imageRef] { - seen[imageRef] = true - images = append(images, imageRef) - } - } - } - } - } - - return images -} - -// installCentralHelmChart installs the central-services Helm chart -func (d *Deployer) installCentralHelmChart(ctx context.Context, chartDir, valuesFile string) error { - d.logger.Info("Installing central-services Helm chart...") - - cmd := exec.CommandContext(ctx, "helm", "install", - "-n", d.centralNamespace, - "stackrox-central-services", - chartDir, - "-f", valuesFile) - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - d.logger.Errorf("helm stdout: %s", stdout.String()) - d.logger.Errorf("helm stderr: %s", stderr.String()) - return fmt.Errorf("failed to install helm chart: %w", err) - } - - d.logger.Success("✓ Helm chart installed") - return nil -} - -// installSecuredClusterHelmChart installs the secured-cluster-services Helm chart -func (d *Deployer) installSecuredClusterHelmChart(ctx context.Context, chartDir, valuesFile, crsFile string) error { - d.logger.Info("Installing secured-cluster-services Helm chart...") - - cmd := exec.CommandContext(ctx, "helm", "install", - "-n", d.sensorNamespace, - "stackrox-secured-cluster-services", - chartDir, - "--set-file", fmt.Sprintf("crs.file=%s", crsFile), - "-f", valuesFile) - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - d.logger.Errorf("helm stdout: %s", stdout.String()) - d.logger.Errorf("helm stderr: %s", stderr.String()) - return fmt.Errorf("failed to install helm chart: %w", err) - } - - d.logger.Success("✓ Helm chart installed") - return nil -} - -// deleteCRDs deletes ACS CRDs (used before Helm deployment) -func (d *Deployer) deleteCRDs(ctx context.Context) { - crds := []string{ - "centrals.platform.stackrox.io", - "securedclusters.platform.stackrox.io", - "securitypolicies.config.stackrox.io", - } - - d.logger.Info("Deleting CRDs...") - - args := append([]string{"delete", "crd", "--ignore-not-found=true"}, crds...) - d.runKubectl(ctx, KubectlOptions{ - Args: args, - IgnoreErrors: true, - }) -} diff --git a/internal/deployer/deploy_via_operator.go b/internal/deployer/deploy_via_operator.go index a8161c69..e1635078 100644 --- a/internal/deployer/deploy_via_operator.go +++ b/internal/deployer/deploy_via_operator.go @@ -579,7 +579,6 @@ func (d *Deployer) fetchCentralCACert(ctx context.Context) error { } // configureCentralEndpoint configures the central endpoint based on exposure settings -// This is shared logic between operator and Helm deployment paths func (d *Deployer) configureCentralEndpoint(ctx context.Context, exposure string) error { if d.portForwardEnabled { // Start port-forward for CLI tool access via localhost:8443 diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index 91b8d188..31f204ce 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -124,7 +124,6 @@ type Deployer struct { securedClusterOverrides map[string]interface{} featureFlagOverrides map[string]interface{} envrcFile string - useHelm bool useOLM bool useKonflux bool shouldDeployOperator bool @@ -579,12 +578,9 @@ func (d *Deployer) Deploy(ctx context.Context, components component.Component, r return d.deployOperatorOnly(ctx) } - // Deploy operator first if needed (unless using Helm) - // Operator is required for central/sensor deployments when not using Helm - if !d.useHelm { - if err := d.ensureOperatorDeployed(ctx); err != nil { - return fmt.Errorf("failed to deploy operator: %w", err) - } + // Deploy operator first if needed + if err := d.ensureOperatorDeployed(ctx); err != nil { + return fmt.Errorf("failed to deploy operator: %w", err) } if components.IncludesCentral() { @@ -628,14 +624,7 @@ func (d *Deployer) deployCentral(ctx context.Context, resources, exposure string portForwardWanted := d.portForwardEnabled - var err error - if d.useHelm { - err = d.deployCentralHelm(ctx, resources, exposure) - } else { - err = d.deployCentralOperator(ctx, resources, exposure) - } - - if err != nil { + if err := d.deployCentralOperator(ctx, resources, exposure); err != nil { return err } @@ -659,9 +648,6 @@ func (d *Deployer) deploySecuredCluster(ctx context.Context, resources string) e } } - if d.useHelm { - return d.deploySecuredClusterHelm(ctx, resources) - } return d.deploySecuredClusterOperator(ctx, resources) } @@ -902,16 +888,6 @@ func (d *Deployer) SetPortForwardingEnabled(enabled bool) { d.portForwardEnabled = enabled } -func (d *Deployer) SetUseHelm(useHelm bool) error { - if useHelm { - if _, err := exec.LookPath("helm"); err != nil { - return errors.New("helm not found in PATH; please install helm and ensure it's available in your PATH when using --helm flag") - } - } - d.useHelm = useHelm - return nil -} - func (d *Deployer) SetUseOLM(useOLM bool) error { d.useOLM = useOLM return nil @@ -1106,7 +1082,6 @@ func (d *Deployer) writeEnvrcFile(ctx context.Context, exposure string, portForw func (d *Deployer) PrintCentralDeploymentSummary() { component := "Central" mainImageTag := d.mainImageTag - helm := d.useHelm olm := d.useOLM exposure := d.exposure portForwarding := d.portForwardEnabled @@ -1163,7 +1138,6 @@ func (d *Deployer) PrintCentralDeploymentSummary() { log.Info(cyan.Sprint("│") + createRow("Cluster Type", env.GetCurrentClusterType().String())) log.Info(cyan.Sprint("│") + createRow("Main Tag", mainImageTag)) log.Info(cyan.Sprint("│") + createRow("Kubernetes Context", kubeContext)) - log.Info(cyan.Sprint("│") + createRow("Deployment Method", map[bool]string{true: "Helm", false: "Operator"}[helm])) if olm { log.Info(cyan.Sprint("│") + createRow("OLM", "Yes")) @@ -1277,7 +1251,6 @@ func (d *Deployer) checkPodProgressInNamespace(ctx context.Context, namespace st func (d *Deployer) PrintSecuredClusterDeploymentSummary() { component := "Secured Cluster" mainImageTag := d.mainImageTag - helm := d.useHelm olm := d.useOLM log := d.logger kubeContext := d.kubeContext @@ -1332,7 +1305,6 @@ func (d *Deployer) PrintSecuredClusterDeploymentSummary() { log.Info(cyan.Sprint("│") + createRow("Cluster Type", env.GetCurrentClusterType().String())) log.Info(cyan.Sprint("│") + createRow("Main Tag", mainImageTag)) log.Info(cyan.Sprint("│") + createRow("Kubernetes Context", kubeContext)) - log.Info(cyan.Sprint("│") + createRow("Deployment Method", map[bool]string{true: "Helm", false: "Operator"}[helm])) if olm { log.Info(cyan.Sprint("│") + createRow("OLM", "Yes")) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 90219a11..5f1f1fcf 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -409,39 +409,6 @@ func TestDeployBothComponentsTogetherInSingleNamespace(t *testing.T) { verifySecuredClusterNotInstalled(t, "stackrox") } -func TestDeployCentralAndSecuredClusterViaHelm(t *testing.T) { - // Create temporary envrc file - envrcFile, err := os.CreateTemp(t.TempDir(), ".envrc.roxie-test-*") - if err != nil { - t.Fatalf("Failed to create temp envrc: %v", err) - } - envrcPath := envrcFile.Name() - envrcFile.Close() - - t.Log("=== Deploying central via Helm ===") - args := append([]string{roxieBinary, "deploy", "--early-readiness", "central", "--helm", "--envrc", envrcPath}, commonDeployArgsNoPortForward...) - runCommand(t, deployTimeout*2, nil, args...) - - // Load environment from envrc file for secured-cluster deployment - envrcEnv, err := loadEnvrcFile(envrcPath) - if err != nil { - t.Fatalf("Failed to load envrc file: %v", err) - } - t.Log("Loaded environment from envrc file for secured-cluster") - - t.Log("=== Deploying secured-cluster via Helm ===") - args = append([]string{roxieBinary, "deploy", "--early-readiness", "secured-cluster", "--helm"}, commonDeployArgsNoPortForward...) - runCommand(t, deployTimeout*2, envrcEnv, args...) - - t.Log("Verifying namespace: acs-central") - verifyNamespaceExists(t, "acs-central") - verifyNamespaceHasLabel(t, "acs-central", "app.kubernetes.io/managed-by", "roxie") - - t.Log("Verifying namespace: acs-sensor") - verifyNamespaceExists(t, "acs-sensor") - verifyNamespaceHasLabel(t, "acs-sensor", "app.kubernetes.io/managed-by", "roxie") -} - func verifyAnnotation(t *testing.T, resourceType, resourceName, namespace, annotationKey, expectedValue string) { t.Helper()