@@ -20,7 +20,6 @@ import (
2020 corev1 "k8s.io/api/core/v1"
2121 rbacv1 "k8s.io/api/rbac/v1"
2222 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
23- apitypes "k8s.io/apimachinery/pkg/types"
2423 apimachyaml "k8s.io/apimachinery/pkg/util/yaml"
2524 "sigs.k8s.io/controller-runtime/pkg/client"
2625 "sigs.k8s.io/controller-runtime/pkg/log"
@@ -72,33 +71,6 @@ type Helm struct {
7271 Client client.Client
7372}
7473
75- func decodeValues (data []byte ) (map [string ]any , error ) {
76- m := map [string ]any {}
77- if len (bytes .TrimSpace (data )) == 0 {
78- return m , nil
79- }
80- j , err := apimachyaml .ToJSON (data )
81- if err != nil {
82- return nil , err
83- }
84- if err := json .Unmarshal (j , & m ); err != nil {
85- return nil , err
86- }
87- return m , nil
88- }
89-
90- func mergeValueMaps (dst , src map [string ]any ) {
91- for k , v := range src {
92- if dstMap , ok := dst [k ].(map [string ]any ); ok {
93- if srcMap , ok2 := v .(map [string ]any ); ok2 {
94- mergeValueMaps (dstMap , srcMap )
95- continue
96- }
97- }
98- dst [k ] = v
99- }
100- }
101-
10274// shouldSkipPreflight is a helper to determine if the preflight check is CRDUpgradeSafety AND
10375// if it is set to enforcement None.
10476func shouldSkipPreflight (ctx context.Context , preflight Preflight , ext * ocv1.ClusterExtension , state string ) bool {
@@ -153,41 +125,55 @@ func (h *Helm) runPreAuthorizationChecks(ctx context.Context, ext *ocv1.ClusterE
153125 return nil
154126}
155127
156- func (h * Helm ) Apply (ctx context.Context , contentFS fs. FS , ext * ocv1.ClusterExtension , objectLabels map [ string ] string , storageLabels map [ string ] string ) ([]client. Object , string , error ) {
157- chrt , err := h . buildHelmChart ( contentFS , ext )
158- if err ! = nil {
159- return nil , "" , err
128+ func (h * Helm ) configValues (ctx context.Context , ext * ocv1.ClusterExtension ) (map [ string ] interface {} , error ) {
129+ cfg := map [ string ] interface {}{}
130+ if ext . Spec . Config = = nil {
131+ return cfg , nil
160132 }
161- // gather configuration values from the ClusterExtension specification
162- // and any referenced Secrets, merging them into a single map
163- valuesMap := map [string ]any {}
164- if ext .Spec .Config != nil {
165- if ext .Spec .Config .Inline != nil && len (ext .Spec .Config .Inline .Raw ) > 0 {
166- inlineMap , err := decodeValues (ext .Spec .Config .Inline .Raw )
167- if err != nil {
168- return nil , "" , fmt .Errorf ("invalid spec.config.inline: %w" , err )
169- }
170- mergeValueMaps (valuesMap , inlineMap )
171- }
172- if ext .Spec .Config .SecretRef != nil {
173- if h .Client == nil {
174- return nil , "" , errors .New ("client is nil" )
175- }
176- secret := & corev1.Secret {}
177- nn := apitypes.NamespacedName {Name : ext .Spec .Config .SecretRef .Name , Namespace : ext .Spec .Namespace }
178- if err := h .Client .Get (ctx , nn , secret ); err != nil {
179- return nil , "" , fmt .Errorf ("failed to get config secret: %w" , err )
180- }
181- data , ok := secret .Data [ext .Spec .Config .SecretRef .Key ]
182- if ! ok {
183- return nil , "" , fmt .Errorf ("secret %q missing key %q" , nn .Name , ext .Spec .Config .SecretRef .Key )
133+ if ext .Spec .Config .Inline != nil {
134+ for k , v := range ext .Spec .Config .Inline {
135+ if len (v .Raw ) == 0 {
136+ cfg [k ] = nil
137+ continue
184138 }
185- secretMap , err := decodeValues ( data )
186- if err != nil {
187- return nil , "" , fmt .Errorf ("invalid config secret %q key %q : %w" , nn . Name , ext . Spec . Config . SecretRef . Key , err )
139+ var val interface {}
140+ if err := json . Unmarshal ( v . Raw , & val ); err != nil {
141+ return nil , fmt .Errorf ("invalid JSON in spec.config.inline[%s] : %w" , k , err )
188142 }
189- mergeValueMaps (valuesMap , secretMap )
143+ cfg [k ] = val
144+ }
145+ }
146+ if ext .Spec .Config .SecretRef != nil {
147+ if h .Client == nil {
148+ return nil , fmt .Errorf ("secretRef specified but Helm client is nil" )
149+ }
150+ secret := & corev1.Secret {}
151+ if err := h .Client .Get (ctx , client.ObjectKey {Name : ext .Spec .Config .SecretRef .Name , Namespace : ext .Spec .Namespace }, secret ); err != nil {
152+ return nil , fmt .Errorf ("failed to get config secret: %w" , err )
190153 }
154+ data , ok := secret .Data [ext .Spec .Config .SecretRef .Key ]
155+ if ! ok {
156+ return nil , fmt .Errorf ("missing key %s in secret %s" , ext .Spec .Config .SecretRef .Key , ext .Spec .Config .SecretRef .Name )
157+ }
158+ var secretCfg map [string ]interface {}
159+ if err := json .Unmarshal (data , & secretCfg ); err != nil {
160+ return nil , fmt .Errorf ("invalid JSON in secret %s/%s: %w" , ext .Spec .Namespace , ext .Spec .Config .SecretRef .Name , err )
161+ }
162+ for k , v := range secretCfg {
163+ cfg [k ] = v
164+ }
165+ }
166+ return cfg , nil
167+ }
168+
169+ func (h * Helm ) Apply (ctx context.Context , contentFS fs.FS , ext * ocv1.ClusterExtension , objectLabels map [string ]string , storageLabels map [string ]string ) ([]client.Object , string , error ) {
170+ chrt , err := h .buildHelmChart (ctx , contentFS , ext )
171+ if err != nil {
172+ return nil , "" , err
173+ }
174+ valuesMap , err := h .configValues (ctx , ext )
175+ if err != nil {
176+ return nil , "" , err
191177 }
192178 values := chartutil.Values {"Values" : valuesMap }
193179
@@ -266,7 +252,7 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.ClusterExte
266252 return relObjects , state , nil
267253}
268254
269- func (h * Helm ) buildHelmChart (bundleFS fs.FS , ext * ocv1.ClusterExtension ) (* chart.Chart , error ) {
255+ func (h * Helm ) buildHelmChart (ctx context. Context , bundleFS fs.FS , ext * ocv1.ClusterExtension ) (* chart.Chart , error ) {
270256 if h .BundleToHelmChartConverter == nil {
271257 return nil , errors .New ("BundleToHelmChartConverter is nil" )
272258 }
@@ -285,14 +271,9 @@ func (h *Helm) buildHelmChart(bundleFS fs.FS, ext *ocv1.ClusterExtension) (*char
285271 }
286272 }
287273
288- // Unmarshal any provided configuration on the ClusterExtension and pass it
289- // to the registry+v1 renderer so that static manifests (e.g. ConfigMaps)
290- // can be overridden with values from spec.config.
291- cfg := map [string ]interface {}{}
292- if ext .Spec .Config != nil && ext .Spec .Config .Raw != nil {
293- if err := json .Unmarshal (ext .Spec .Config .Raw , & cfg ); err != nil {
294- return nil , fmt .Errorf ("invalid JSON in spec.config: %w" , err )
295- }
274+ cfg , err := h .configValues (ctx , ext )
275+ if err != nil {
276+ return nil , err
296277 }
297278
298279 return h .BundleToHelmChartConverter .ToHelmChartWithConfig (source .FromFS (bundleFS ), ext .Spec .Namespace , watchNamespace , cfg )
0 commit comments