@@ -18,17 +18,25 @@ package controller
18
18
19
19
import (
20
20
"context"
21
+ "encoding/json"
22
+ "fmt"
23
+ "regexp"
24
+ "slices"
25
+ "strings"
21
26
22
27
controlplanev1alpha2 "github.com/openshift-assisted/cluster-api-agent/controlplane/api/v1alpha2"
23
28
"github.com/openshift-assisted/cluster-api-agent/controlplane/internal/imageregistry"
24
29
"github.com/openshift-assisted/cluster-api-agent/controlplane/internal/release"
25
30
"github.com/openshift-assisted/cluster-api-agent/util"
26
31
logutil "github.com/openshift-assisted/cluster-api-agent/util/log"
32
+
27
33
configv1 "github.com/openshift/api/config/v1"
28
34
hiveext "github.com/openshift/assisted-service/api/hiveextension/v1beta1"
29
35
aiv1beta1 "github.com/openshift/assisted-service/api/v1beta1"
30
36
hivev1 "github.com/openshift/hive/apis/hive/v1"
37
+
31
38
corev1 "k8s.io/api/core/v1"
39
+ "k8s.io/apimachinery/pkg/api/equality"
32
40
apierrors "k8s.io/apimachinery/pkg/api/errors"
33
41
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34
42
"k8s.io/apimachinery/pkg/runtime"
@@ -40,7 +48,13 @@ import (
40
48
)
41
49
42
50
const (
43
- InstallConfigOverrides = aiv1beta1 .Group + "/install-config-overrides"
51
+ InstallConfigOverrides = aiv1beta1 .Group + "/install-config-overrides"
52
+ defaultBaremetalBaselineCapability = "None"
53
+ defaultBaselineCapability = "vCurrent"
54
+ )
55
+
56
+ var (
57
+ defaultBaremetalAdditionalCapabilities = []configv1.ClusterVersionCapability {"baremetal" , "Console" , "Insights" , "OperatorLifecycleManager" , "Ingress" }
44
58
)
45
59
46
60
// ClusterDeploymentReconciler reconciles a ClusterDeployment object
@@ -250,9 +264,9 @@ func (r *ClusterDeploymentReconciler) computeAgentClusterInstall(
250
264
aci .Spec .APIVIPs = acp .Spec .Config .APIVIPs
251
265
aci .Spec .IngressVIPs = acp .Spec .Config .IngressVIPs
252
266
aci .Spec .PlatformType = hiveext .PlatformType (configv1 .BareMetalPlatformType )
253
- aci . Annotations = map [ string ] string {
254
- InstallConfigOverrides : `{"capabilities": {"baselineCapabilitySet": "None", "additionalEnabledCapabilities": ["baremetal","Console","Insights","OperatorLifecycleManager","Ingress"]}}"` ,
255
- }
267
+ }
268
+ if err := setACICapabilities ( & acp , aci ); err != nil {
269
+ return nil , err
256
270
}
257
271
return aci , nil
258
272
}
@@ -273,3 +287,88 @@ func (r *ClusterDeploymentReconciler) createImageRegistry(ctx context.Context, r
273
287
}
274
288
return nil
275
289
}
290
+
291
+ type InstallConfigOverride struct {
292
+ Capability configv1.ClusterVersionCapabilitiesSpec `json:"capabilities,omitempty"`
293
+ }
294
+
295
+ // setACICapabilities will set the install config override annotation in the AgentClusterInstall if there
296
+ // are additional enabled capabilities that need to be defined.
297
+ // For SNO (single node openshift) and non-baremetal platform MNO (multi-node openshift), this is set if
298
+ // the OpenshiftAssistedControlPlane has additional capabilities set.
299
+ // For MNO (multi-node openshift), this is set to the default list for baremetal platform,
300
+ // but the OpenshiftAssistedControlPlane can specify additional capabilities to be appended to this list.
301
+ func setACICapabilities (oacp * controlplanev1alpha2.OpenshiftAssistedControlPlane , aci * hiveext.AgentClusterInstall ) error {
302
+ isBaremetalPlatform := aci .Spec .PlatformType == hiveext .BareMetalPlatformType
303
+ if isCapabilitiesEmpty (oacp .Spec .Config .Capabilities ) && ! isBaremetalPlatform {
304
+ return nil
305
+ }
306
+ var installCfgOverride InstallConfigOverride
307
+ baselineCapability , err := getBaselineCapability (oacp .Spec .Config .Capabilities .BaselineCapability , isBaremetalPlatform )
308
+ if err != nil {
309
+ return err
310
+ }
311
+ installCfgOverride .Capability .BaselineCapabilitySet = configv1 .ClusterVersionCapabilitySet (baselineCapability )
312
+
313
+ additionalEnabledCapabilities := getAdditionalCapabilities (oacp .Spec .Config .Capabilities .AdditionalEnabledCapabilities , isBaremetalPlatform )
314
+ installCfgOverride .Capability .AdditionalEnabledCapabilities = additionalEnabledCapabilities
315
+
316
+ installCfgOverrideStr , err := json .Marshal (installCfgOverride )
317
+ if err != nil {
318
+ return err
319
+ }
320
+
321
+ if aci .Annotations == nil {
322
+ aci .Annotations = make (map [string ]string )
323
+ }
324
+
325
+ aci .Annotations [InstallConfigOverrides ] = string (installCfgOverrideStr )
326
+ return nil
327
+ }
328
+
329
+ func getBaselineCapability (capability string , isBaremetalPlatform bool ) (string , error ) {
330
+ baselineCapability := capability
331
+ if baselineCapability == "None" || baselineCapability == "vCurrent" {
332
+ return baselineCapability , nil
333
+ }
334
+
335
+ if baselineCapability == "" {
336
+ baselineCapability = defaultBaselineCapability
337
+ if isBaremetalPlatform {
338
+ baselineCapability = defaultBaremetalBaselineCapability
339
+ }
340
+ return baselineCapability , nil
341
+ }
342
+
343
+ var baselineCapabilityRegexp = regexp .MustCompile (`v4\.[0-9]+` )
344
+ if ! baselineCapabilityRegexp .MatchString (baselineCapability ) {
345
+ return "" ,
346
+ fmt .Errorf ("invalid baseline capability set, must be one of: None, vCurrent, or v4.x. Got: [%s]" , baselineCapability )
347
+ }
348
+ return baselineCapability , nil
349
+ }
350
+
351
+ func getAdditionalCapabilities (specifiedAdditionalCapabilities []string , isBaremetalPlatform bool ) []configv1.ClusterVersionCapability {
352
+ additionalCapabilitiesList := []configv1.ClusterVersionCapability {}
353
+ if isBaremetalPlatform {
354
+ additionalCapabilitiesList = append ([]configv1.ClusterVersionCapability {}, defaultBaremetalAdditionalCapabilities ... )
355
+ }
356
+
357
+ for _ , capability := range specifiedAdditionalCapabilities {
358
+ // Ignore MAPI for baremetal MNO clusters and ignore duplicates
359
+ if (strings .EqualFold (capability , "MachineAPI" ) && isBaremetalPlatform ) || slices .Contains (additionalCapabilitiesList , configv1 .ClusterVersionCapability (capability )) {
360
+ continue
361
+ }
362
+ additionalCapabilitiesList = append (additionalCapabilitiesList , configv1 .ClusterVersionCapability (capability ))
363
+ }
364
+
365
+ if len (additionalCapabilitiesList ) < 1 {
366
+ return nil
367
+ }
368
+
369
+ return additionalCapabilitiesList
370
+ }
371
+
372
+ func isCapabilitiesEmpty (capabilities controlplanev1alpha2.Capabilities ) bool {
373
+ return equality .Semantic .DeepEqual (capabilities , controlplanev1alpha2.Capabilities {})
374
+ }
0 commit comments