Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Examples:

cmd.Flags().BoolVar(&helm, "helm", false, "Deploy using Helm charts instead of operator")
cmd.Flags().BoolVar(&olm, "olm", false, "Deploy operator via OLM (requires OLM installed)")
cmd.Flags().BoolVar(&deployOperator, "deploy-operator", true, "Deploy and check operator (set to false to skip operator deployment/checks)")
cmd.Flags().BoolVar(&portForwarding, "port-forwarding", false, "Enable localhost port-forward for Central")
cmd.Flags().BoolVar(&pauseReconciliation, "pause-reconciliation", false, "Pause reconciliation after deployment")
cmd.Flags().StringVar(&overrideFile, "override", "", "Path to YAML file with overrides")
Expand Down Expand Up @@ -91,6 +92,15 @@ func runDeploy(cmd *cobra.Command, args []string) error {
os.Setenv("KUBECONFIG", "/kubeconfig")
}

// Validate flag combinations early
if helm && olm {
return errors.New("cannot use both --helm and --olm flags together")
}

if !deployOperator && olm {
return errors.New("cannot use --deploy-operator=false with --olm (OLM requires operator deployment)")
}

d, err := deployer.New(log, overrideFile, overrideSetExpressions)
if err != nil {
return fmt.Errorf("failed to create deployer: %w", err)
Expand All @@ -107,10 +117,6 @@ func runDeploy(cmd *cobra.Command, args []string) error {
d.SetEnvrcFile(envrc)
}

if helm && olm {
return errors.New("cannot use both --helm and --olm flags together")
}

if helm {
if err := d.SetUseHelm(true); err != nil {
return err
Expand All @@ -123,6 +129,8 @@ func runDeploy(cmd *cobra.Command, args []string) error {
}
}

d.SetDeployOperator(deployOperator)

d.SetVerbose(verbose)
d.SetEarlyReadiness(earlyReadiness)
d.SetPortForwardingEnabled(portForwardEnabledFinal)
Expand Down
1 change: 1 addition & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var (
earlyReadiness bool
helm bool
olm bool
deployOperator bool
portForwarding bool
pauseReconciliation bool
overrideFile string
Expand Down
123 changes: 121 additions & 2 deletions internal/deployer/deploy_via_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import (

// ensureOperatorDeployed ensures the operator is deployed with the correct version and mode
func (d *Deployer) ensureOperatorDeployed(ctx context.Context) error {
// Skip operator deployment/checks if flag is set to false
if !d.shouldDeployOperator {
d.logger.Info("ℹ️ Skipping operator deployment checks (--deploy-operator=false)")
d.logger.Info(" Assuming operator is already running...")
return nil
}

if err := d.ensureCRDsInstalled(ctx); err != nil {
return fmt.Errorf("failed to ensure CRDs installed: %w", err)
}
Expand Down Expand Up @@ -263,13 +270,14 @@ func (d *Deployer) createCentralCR(resources, exposure string) (map[string]inter
}

resourcesOverlay := d.getCentralResourcesOperator(resources)
imageOverlay := d.getCentralImageOverlays()

overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
if err != nil {
return nil, fmt.Errorf("failed construct Central CR overrides: %w", err)
}

merged := helpers.MergeMaps(base, resourcesOverlay, overrides)
merged := helpers.MergeMaps(base, resourcesOverlay, imageOverlay, overrides)

return merged, nil
}
Expand Down Expand Up @@ -337,6 +345,43 @@ func (d *Deployer) getCentralResourcesOperator(resourcesName string) map[string]
return resources
}

// getCentralImageOverlays returns image tag overlays for Central components
func (d *Deployer) getCentralImageOverlays() map[string]interface{} {
if d.mainImageTag == "" {
return map[string]interface{}{}
}

// Create overlays to set the image tag for all Central deployments.
overlays := []map[string]interface{}{
d.mainImageOverlays("Deployment", "central", map[string]string{
"central": "main",
}),
d.mainImageOverlays("Deployment", "config-controller", map[string]string{
"manager": "main",
}),
d.mainImageOverlays("Deployment", "central-db", map[string]string{
"init:init-db": "central-db",
"central-db": "central-db",
}),
d.mainImageOverlays("Deployment", "scanner-v4-indexer", map[string]string{
"indexer": "scanner-v4",
}),
d.mainImageOverlays("Deployment", "scanner-v4-matcher", map[string]string{
"matcher": "scanner-v4",
}),
d.mainImageOverlays("Deployment", "scanner-v4-db", map[string]string{
"init:init-db": "scanner-v4-db",
"db": "scanner-v4-db",
}),
}

return map[string]interface{}{
"spec": map[string]interface{}{
"overlays": overlays,
},
}
}

// getCentralExposureConfig returns the exposure configuration
func (d *Deployer) getCentralExposureConfig(exposure string) map[string]interface{} {
switch exposure {
Expand Down Expand Up @@ -642,13 +687,14 @@ func (d *Deployer) createSecuredClusterCR(clusterName, resources string) (map[st
}

resourcesOverlay := d.getSecuredClusterResourcesOperator(resources)
imageOverlay := d.getSecuredClusterImageOverlays()

overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
if err != nil {
return nil, fmt.Errorf("failed construct Central CR overrides: %w", err)
}

merged := helpers.MergeMaps(base, resourcesOverlay, overrides)
merged := helpers.MergeMaps(base, resourcesOverlay, imageOverlay, overrides)

return merged, nil
}
Expand Down Expand Up @@ -694,6 +740,79 @@ func (d *Deployer) getSecuredClusterResourcesOperator(resourcesName string) map[
return resources
}

func (d *Deployer) mainImageOverlays(kind, name string, containerImages map[string]string) map[string]interface{} {
patches := make([]map[string]interface{}, 0, len(containerImages))
for containerName, containerImage := range containerImages {
containerType := "containers"
containerComponents := strings.SplitN(containerName, ":", 2)
Comment thread
mclasmeier marked this conversation as resolved.
if len(containerComponents) == 2 {
if containerComponents[0] == "init" {
containerType = "initContainers"
containerName = containerComponents[1]
} else {
panic(fmt.Sprintf("invalid container type: %s", containerComponents[0]))
}
}
patchPath := fmt.Sprintf("spec.template.spec.%s[name:%s].image", containerType, containerName)
patches = append(patches, map[string]interface{}{
"path": patchPath,
"value": fmt.Sprintf("quay.io/rhacs-eng/%s:%s", containerImage, d.mainImageTag),
})
}
return map[string]interface{}{
"apiVersion": "apps/v1",
"kind": kind,
"name": name,
"optional": true,
"patches": patches,
}
}

// getSecuredClusterImageOverlays returns image tag overlays for SecuredCluster components
func (d *Deployer) getSecuredClusterImageOverlays() map[string]interface{} {
if d.mainImageTag == "" {
return map[string]interface{}{}
}

// Create overlays to set the image tag for all SecuredCluster deployments.
overlays := []map[string]interface{}{
d.mainImageOverlays("Deployment", "sensor", map[string]string{
"init:crs": "main",
"init:init-tls-certs": "main",
"sensor": "main",
}),
d.mainImageOverlays("Deployment", "admission-control", map[string]string{
"init:init-tls-certs": "main",
"admission-control": "main",
}),
d.mainImageOverlays("DaemonSet", "collector", map[string]string{
"init:init-tls-certs": "main",
"compliance": "main",
}),
d.mainImageOverlays("Deployment", "scanner-v4-indexer", map[string]string{
"init:init-tls-certs": "main",
"indexer": "scanner-v4",
}),
d.mainImageOverlays("Deployment", "scanner-v4-db", map[string]string{
"init:init-tls-certs": "main",
"init:init-db": "scanner-v4-db",
"db": "scanner-v4-db",
}),
d.mainImageOverlays("Deployment", "scanner", map[string]string{
"init:init-tls-certs": "main",
}),
d.mainImageOverlays("Deployment", "scanner-db", map[string]string{
"init:init-tls-certs": "main",
}),
}

return map[string]interface{}{
"spec": map[string]interface{}{
"overlays": overlays,
},
}
}

// applySecuredClusterCR applies the SecuredCluster CR to the cluster
func (d *Deployer) applySecuredClusterCR(ctx context.Context, cr map[string]interface{}) error {
d.logger.Info("Applying SecuredCluster custom resource")
Expand Down
6 changes: 6 additions & 0 deletions internal/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type Deployer struct {
envrcFile string
useHelm bool
useOLM bool
shouldDeployOperator bool
verbose bool
earlyReadiness bool
dockerCreds *dockerauth.Credentials
Expand Down Expand Up @@ -84,6 +85,7 @@ func New(log *logger.Logger, overrideFile string, overrideSetExpressions []strin
exposure: defaultExposure,
overrideFile: overrideFile,
overrideSetExpressions: overrideSetExpressions,
shouldDeployOperator: true,
}

d.dockerAuth = dockerauth.New(log)
Expand Down Expand Up @@ -553,6 +555,10 @@ func (d *Deployer) removePauseReconcileAnnotation(ctx context.Context, resourceT
}
}

func (d *Deployer) SetDeployOperator(deployOperator bool) {
d.shouldDeployOperator = deployOperator
}

func (d *Deployer) GetDeploymentInfo() (endpoint, password, caCertFile, kubeContext, exposure string) {
return d.centralEndpoint, d.centralPassword, d.roxCACertFile, d.kubeContext, d.exposure
}
Expand Down