Skip to content

Commit fd54576

Browse files
mclasmeierMoritz Clasmeier
andauthored
Rework override handling to properly support combined deployments (#62)
Co-authored-by: Moritz Clasmeier <mclasmeier@redhat.com>
1 parent 99dcd19 commit fd54576

6 files changed

Lines changed: 206 additions & 112 deletions

File tree

cmd/deploy.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,41 @@ func runDeploy(cmd *cobra.Command, args []string) error {
132132
return errors.New("cannot use --deploy-operator=false with --olm (OLM requires operator deployment)")
133133
}
134134

135-
d, err := deployer.New(log, overrideFile, overrideSetExpressions)
135+
d, err := deployer.New(log)
136136
if err != nil {
137137
return fmt.Errorf("failed to create deployer: %w", err)
138138
}
139139

140+
if overrideFile != "" {
141+
var err error
142+
switch component {
143+
case "both", "all":
144+
err = d.SetCombinedOverrideFile(overrideFile)
145+
case "central":
146+
err = d.SetCentralOverrideFile(overrideFile)
147+
case "secured-cluster":
148+
err = d.SetSecuredClusterOverrideFile(overrideFile)
149+
}
150+
if err != nil {
151+
return fmt.Errorf("failed to set override file: %w", err)
152+
}
153+
}
154+
155+
if len(overrideSetExpressions) > 0 {
156+
var err error
157+
switch component {
158+
case "both", "all":
159+
err = d.SetCombinedOverrideSetExpressions(overrideSetExpressions)
160+
case "central":
161+
err = d.SetCentralOverrideSetExpressions(overrideSetExpressions)
162+
case "secured-cluster":
163+
err = d.SetSecuredClusterOverrideSetExpressions(overrideSetExpressions)
164+
}
165+
if err != nil {
166+
return fmt.Errorf("failed to set override set expressions: %w", err)
167+
}
168+
}
169+
140170
switch component {
141171
case "central", "both", "all":
142172
d.PrintCentralDeploymentSummary()

cmd/teardown.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func runTeardown(cmd *cobra.Command, args []string) error {
4141

4242
log.Infof("Tearing down %s", component)
4343

44-
d, err := deployer.New(log, "", []string{})
44+
d, err := deployer.New(log)
4545
if err != nil {
4646
return fmt.Errorf("failed to create deployer: %w", err)
4747
}

internal/deployer/deploy_via_helm.go

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,7 @@ func (d *Deployer) createCentralValues(resourcesName, exposure string) (map[stri
259259

260260
resourcesOverlay := d.getCentralResourcesHelm(resourcesName)
261261

262-
overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
263-
if err != nil {
264-
return nil, fmt.Errorf("failed construct Central Helm values overrides: %w", err)
265-
}
266-
267-
merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, overrides)
262+
merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, d.centralOverrides)
268263

269264
return merged, nil
270265
}
@@ -292,12 +287,7 @@ func (d *Deployer) createSecuredClusterValues(clusterName, resources string) (ma
292287

293288
resourcesOverlay := d.getSecuredClusterResourcesHelm(resources)
294289

295-
overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
296-
if err != nil {
297-
return nil, fmt.Errorf("failed construct Central Helm values overrides: %w", err)
298-
}
299-
300-
merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, overrides)
290+
merged := helpers.MergeMaps(base, imageSettings, resourcesOverlay, d.securedClusterOverrides)
301291

302292
return merged, nil
303293
}
@@ -553,8 +543,3 @@ func (d *Deployer) deleteCRDs(ctx context.Context) {
553543
IgnoreErrors: true,
554544
})
555545
}
556-
557-
// SetOverrideFile sets the path to the override values file
558-
func (d *Deployer) SetOverrideFile(path string) {
559-
d.overrideFile = path
560-
}

internal/deployer/deploy_via_operator.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,7 @@ func (d *Deployer) createCentralCR(resources, exposure string) (map[string]inter
263263
d.logger.Infof("Using Central resource profile: %s", resources)
264264
resourcesOverlay := d.getCentralResourcesOperator(resources)
265265

266-
overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
267-
if err != nil {
268-
return nil, fmt.Errorf("failed construct Central CR overrides: %w", err)
269-
}
270-
271-
merged := helpers.MergeMaps(base, resourcesOverlay, overrides)
266+
merged := helpers.MergeMaps(base, resourcesOverlay, d.centralOverrides)
272267

273268
return merged, nil
274269
}
@@ -667,12 +662,7 @@ func (d *Deployer) createSecuredClusterCR(clusterName, resources string) (map[st
667662

668663
resourcesOverlay := d.getSecuredClusterResourcesOperator(resources)
669664

670-
overrides, err := GetOverrides(d.overrideFile, d.overrideSetExpressions)
671-
if err != nil {
672-
return nil, fmt.Errorf("failed construct Central CR overrides: %w", err)
673-
}
674-
675-
merged := helpers.MergeMaps(base, resourcesOverlay, overrides)
665+
merged := helpers.MergeMaps(base, resourcesOverlay, d.securedClusterOverrides)
676666

677667
return merged, nil
678668
}

internal/deployer/deployer.go

Lines changed: 170 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/fatih/color"
14+
"gopkg.in/yaml.v3"
1415

1516
"github.com/stackrox/roxie/internal/clusterdefaults"
1617
"github.com/stackrox/roxie/internal/dockerauth"
@@ -89,36 +90,36 @@ var (
8990

9091
// Deployer is the base deployer for ACS
9192
type Deployer struct {
92-
logger *logger.Logger
93-
startTime time.Time
94-
dockerAuth *dockerauth.DockerAuth
95-
imageCache *imagecache.ImageCache
96-
portForward *portforward.Manager
97-
clusterDefaults *clusterdefaults.Manager
98-
kubectl string
99-
roxctlVersion string
100-
centralNamespace string
101-
sensorNamespace string
102-
mainImageTag string
103-
operatorTag string
104-
centralEndpoint string
105-
centralPassword string
106-
roxCACertFile string
107-
kubeContext string
108-
portForwardEnabled bool
109-
pauseReconciliation bool
110-
exposure string
111-
overrideFile string
112-
overrideSetExpressions []string
113-
envrcFile string
114-
useHelm bool
115-
useOLM bool
116-
useKonflux bool
117-
shouldDeployOperator bool
118-
verbose bool
119-
earlyReadiness bool
120-
dockerCreds *dockerauth.Credentials
121-
clusterResourceKinds map[string]struct{}
93+
logger *logger.Logger
94+
startTime time.Time
95+
dockerAuth *dockerauth.DockerAuth
96+
imageCache *imagecache.ImageCache
97+
portForward *portforward.Manager
98+
clusterDefaults *clusterdefaults.Manager
99+
kubectl string
100+
roxctlVersion string
101+
centralNamespace string
102+
sensorNamespace string
103+
mainImageTag string
104+
operatorTag string
105+
centralEndpoint string
106+
centralPassword string
107+
roxCACertFile string
108+
kubeContext string
109+
portForwardEnabled bool
110+
pauseReconciliation bool
111+
exposure string
112+
centralOverrides map[string]interface{}
113+
securedClusterOverrides map[string]interface{}
114+
envrcFile string
115+
useHelm bool
116+
useOLM bool
117+
useKonflux bool
118+
shouldDeployOperator bool
119+
verbose bool
120+
earlyReadiness bool
121+
dockerCreds *dockerauth.Credentials
122+
clusterResourceKinds map[string]struct{}
122123
}
123124

124125
type ResourceKindWithName struct {
@@ -308,7 +309,137 @@ func (d *Deployer) deleteSecuredClusterResources(ctx context.Context, wait bool)
308309
return nil
309310
}
310311

311-
func New(log *logger.Logger, overrideFile string, overrideSetExpressions []string) (*Deployer, error) {
312+
var (
313+
centralOverridePrefix = "central"
314+
securedClusterOverridePrefix = "securedCluster"
315+
)
316+
317+
func unmarshalYamlFile(filePath string) (map[string]interface{}, error) {
318+
rawContent, err := os.ReadFile(filePath)
319+
if err != nil {
320+
return nil, fmt.Errorf("failed to read override file: %w", err)
321+
}
322+
var content map[string]interface{}
323+
if err := yaml.Unmarshal(rawContent, &content); err != nil {
324+
return nil, fmt.Errorf("failed to parse override file: %w", err)
325+
}
326+
return content, nil
327+
}
328+
329+
func (d *Deployer) SetCombinedOverrideFile(overrideFile string) error {
330+
overrides, err := unmarshalYamlFile(overrideFile)
331+
if err != nil {
332+
return fmt.Errorf("failed to unmarshal override file: %w", err)
333+
}
334+
335+
for key, value := range overrides {
336+
switch key {
337+
case centralOverridePrefix:
338+
d.centralOverrides = value.(map[string]interface{})
339+
case securedClusterOverridePrefix:
340+
d.securedClusterOverrides = value.(map[string]interface{})
341+
default:
342+
d.logger.Errorf("override file contains key %q; combined deployments require extra nesting under 'central' or 'securedCluster'", key)
343+
return fmt.Errorf("unexpected key %q in override file", key)
344+
}
345+
}
346+
347+
return nil
348+
}
349+
350+
// Returns remaining set expressions.
351+
func setOverrideSetExpressions(overrides map[string]interface{}, prefix string, overrideSetExpressions []string) ([]string, error) {
352+
remainingSetExpressions := make([]string, 0)
353+
for _, expr := range overrideSetExpressions {
354+
parts := splitAtFirstEquals(expr)
355+
if len(parts) != 2 {
356+
return nil, fmt.Errorf("invalid override expression '%s': expected format 'key.path=value'", expr)
357+
}
358+
key := parts[0]
359+
if prefix != "" {
360+
if !strings.HasPrefix(parts[0], prefix) {
361+
remainingSetExpressions = append(remainingSetExpressions, expr)
362+
continue
363+
}
364+
key = strings.TrimPrefix(key, prefix+".")
365+
}
366+
var val interface{}
367+
if err := yaml.Unmarshal([]byte(parts[1]), &val); err != nil {
368+
return nil, fmt.Errorf("failed to unmarshal value '%s' for key '%s': %w", parts[1], key, err)
369+
}
370+
if err := setNestedValue(overrides, key, val); err != nil {
371+
return nil, fmt.Errorf("failed to set value for key '%s': %w", key, err)
372+
}
373+
}
374+
375+
return remainingSetExpressions, nil
376+
}
377+
378+
func (d *Deployer) SetCombinedOverrideSetExpressions(overrideSetExpressions []string) error {
379+
if d.centralOverrides == nil {
380+
d.centralOverrides = make(map[string]interface{})
381+
}
382+
if d.securedClusterOverrides == nil {
383+
d.securedClusterOverrides = make(map[string]interface{})
384+
}
385+
386+
remainingSetExpressions, err := setOverrideSetExpressions(d.centralOverrides, centralOverridePrefix, overrideSetExpressions)
387+
if err != nil {
388+
return fmt.Errorf("failed to set central override set expressions: %w", err)
389+
}
390+
remainingSetExpressions, err = setOverrideSetExpressions(d.securedClusterOverrides, securedClusterOverridePrefix, remainingSetExpressions)
391+
if err != nil {
392+
return fmt.Errorf("failed to set secured cluster override set expressions: %w", err)
393+
}
394+
395+
if len(remainingSetExpressions) > 0 {
396+
return fmt.Errorf("some override expressions were not properly prefixed with 'central.' or 'securedCluster.': %v", remainingSetExpressions)
397+
}
398+
399+
return nil
400+
}
401+
402+
func (d *Deployer) SetCentralOverrideFile(overrideYaml string) error {
403+
centralOverrides, err := unmarshalYamlFile(overrideYaml)
404+
if err != nil {
405+
return fmt.Errorf("failed to unmarshal override file: %w", err)
406+
}
407+
d.centralOverrides = centralOverrides
408+
return nil
409+
}
410+
411+
func (d *Deployer) SetCentralOverrideSetExpressions(overrideSetExpressions []string) error {
412+
if d.centralOverrides == nil {
413+
d.centralOverrides = make(map[string]interface{})
414+
}
415+
_, err := setOverrideSetExpressions(d.centralOverrides, "", overrideSetExpressions)
416+
if err != nil {
417+
return fmt.Errorf("failed to set central override set expressions: %w", err)
418+
}
419+
return nil
420+
}
421+
422+
func (d *Deployer) SetSecuredClusterOverrideFile(overrideYaml string) error {
423+
securedClusterOverrides, err := unmarshalYamlFile(overrideYaml)
424+
if err != nil {
425+
return fmt.Errorf("failed to unmarshal override file: %w", err)
426+
}
427+
d.securedClusterOverrides = securedClusterOverrides
428+
return nil
429+
}
430+
431+
func (d *Deployer) SetSecuredClusterOverrideSetExpressions(overrideSetExpressions []string) error {
432+
if d.securedClusterOverrides == nil {
433+
d.securedClusterOverrides = make(map[string]interface{})
434+
}
435+
_, err := setOverrideSetExpressions(d.securedClusterOverrides, "", overrideSetExpressions)
436+
if err != nil {
437+
return fmt.Errorf("failed to set secured cluster override set expressions: %w", err)
438+
}
439+
return nil
440+
}
441+
442+
func New(log *logger.Logger) (*Deployer, error) {
312443
// Check required tools first
313444
if err := checkRequiredTools(); err != nil {
314445
return nil, err
@@ -322,16 +453,14 @@ func New(log *logger.Logger, overrideFile string, overrideSetExpressions []strin
322453
kubectl := getKubectl()
323454

324455
d := &Deployer{
325-
logger: log,
326-
startTime: time.Now(),
327-
kubectl: kubectl,
328-
roxctlVersion: roxctlVersion,
329-
centralNamespace: centralNamespace,
330-
sensorNamespace: sensorNamespace,
331-
exposure: defaultExposure,
332-
overrideFile: overrideFile,
333-
overrideSetExpressions: overrideSetExpressions,
334-
shouldDeployOperator: true,
456+
logger: log,
457+
startTime: time.Now(),
458+
kubectl: kubectl,
459+
roxctlVersion: roxctlVersion,
460+
centralNamespace: centralNamespace,
461+
sensorNamespace: sensorNamespace,
462+
exposure: defaultExposure,
463+
shouldDeployOperator: true,
335464
}
336465

337466
d.dockerAuth = dockerauth.New(log)

0 commit comments

Comments
 (0)