@@ -20,7 +20,6 @@ import (
20
20
corev1 "k8s.io/api/core/v1"
21
21
rbacv1 "k8s.io/api/rbac/v1"
22
22
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
23
- apitypes "k8s.io/apimachinery/pkg/types"
24
23
apimachyaml "k8s.io/apimachinery/pkg/util/yaml"
25
24
"sigs.k8s.io/controller-runtime/pkg/client"
26
25
"sigs.k8s.io/controller-runtime/pkg/log"
@@ -72,33 +71,6 @@ type Helm struct {
72
71
Client client.Client
73
72
}
74
73
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
-
102
74
// shouldSkipPreflight is a helper to determine if the preflight check is CRDUpgradeSafety AND
103
75
// if it is set to enforcement None.
104
76
func 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
153
125
return nil
154
126
}
155
127
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
160
132
}
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
184
138
}
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 )
188
142
}
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 )
190
153
}
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
191
177
}
192
178
values := chartutil.Values {"Values" : valuesMap }
193
179
@@ -266,7 +252,7 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.ClusterExte
266
252
return relObjects , state , nil
267
253
}
268
254
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 ) {
270
256
if h .BundleToHelmChartConverter == nil {
271
257
return nil , errors .New ("BundleToHelmChartConverter is nil" )
272
258
}
@@ -285,14 +271,9 @@ func (h *Helm) buildHelmChart(bundleFS fs.FS, ext *ocv1.ClusterExtension) (*char
285
271
}
286
272
}
287
273
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
296
277
}
297
278
298
279
return h .BundleToHelmChartConverter .ToHelmChartWithConfig (source .FromFS (bundleFS ), ext .Spec .Namespace , watchNamespace , cfg )
0 commit comments