Skip to content

Commit 8f6e183

Browse files
committed
pkg: Allow baremetal platform without MachineAPI capability
There are use cases for using the baremetal platform while disabling MAPI (for example to use CAPI). The installer will skip rendering BMH, Machine and MachineSet CRs in case MAPI is disabled This also removes the validation preventing this configuration to allow users to create the ignition-configs. The validations still apply for the create cluster target Fixes METAL-1039 Signed-off-by: Eran Cohen <[email protected]>
1 parent 82294b4 commit 8f6e183

File tree

8 files changed

+94
-57
lines changed

8 files changed

+94
-57
lines changed

pkg/asset/installconfig/platformprovisioncheck.go

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"errors"
66
"fmt"
77

8-
"k8s.io/apimachinery/pkg/util/sets"
8+
"k8s.io/apimachinery/pkg/util/validation/field"
99

1010
configv1 "github.com/openshift/api/config/v1"
1111
"github.com/openshift/installer/pkg/asset"
@@ -22,6 +22,7 @@ import (
2222
"github.com/openshift/installer/pkg/types/aws"
2323
"github.com/openshift/installer/pkg/types/azure"
2424
"github.com/openshift/installer/pkg/types/baremetal"
25+
baremetalvalidation "github.com/openshift/installer/pkg/types/baremetal/validation"
2526
"github.com/openshift/installer/pkg/types/external"
2627
"github.com/openshift/installer/pkg/types/gcp"
2728
"github.com/openshift/installer/pkg/types/ibmcloud"
@@ -54,28 +55,8 @@ func (a *PlatformProvisionCheck) Generate(dependencies asset.Parents) error {
5455
platform := ic.Config.Platform.Name()
5556

5657
// IPI requires MachineAPI capability
57-
enabledCaps := sets.NewString()
58-
if ic.Config.Capabilities == nil || ic.Config.Capabilities.BaselineCapabilitySet == "" {
59-
// when Capabilities and/or BaselineCapabilitySet is not specified, default is vCurrent
60-
baseSet := configv1.ClusterVersionCapabilitySets[configv1.ClusterVersionCapabilitySetCurrent]
61-
for _, cap := range baseSet {
62-
enabledCaps.Insert(string(cap))
63-
}
64-
}
65-
if ic.Config.Capabilities != nil {
66-
if ic.Config.Capabilities.BaselineCapabilitySet != "" {
67-
baseSet := configv1.ClusterVersionCapabilitySets[ic.Config.Capabilities.BaselineCapabilitySet]
68-
for _, cap := range baseSet {
69-
enabledCaps.Insert(string(cap))
70-
}
71-
}
72-
if ic.Config.Capabilities.AdditionalEnabledCapabilities != nil {
73-
for _, cap := range ic.Config.Capabilities.AdditionalEnabledCapabilities {
74-
enabledCaps.Insert(string(cap))
75-
}
76-
}
77-
}
78-
if !enabledCaps.Has(string(configv1.ClusterVersionCapabilityMachineAPI)) {
58+
enabledCaps := ic.Config.GetEnabledCapabilities()
59+
if !enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
7960
return errors.New("IPI requires MachineAPI capability")
8061
}
8162

@@ -114,6 +95,11 @@ func (a *PlatformProvisionCheck) Generate(dependencies asset.Parents) error {
11495
if err != nil {
11596
return err
11697
}
98+
err = baremetalvalidation.ValidateHosts(ic.Config.BareMetal, field.NewPath("platform"), ic.Config).ToAggregate()
99+
if err != nil {
100+
return err
101+
}
102+
117103
case gcp.Name:
118104
err := gcpconfig.ValidateForProvisioning(ic.Config)
119105
if err != nil {

pkg/asset/machines/master.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ func (m *Master) GenerateWithContext(ctx context.Context, dependencies asset.Par
395395
// Use managed user data secret, since we always have up to date images
396396
// available in the cluster
397397
masterUserDataSecretName = "master-user-data-managed"
398+
enabledCaps := installConfig.Config.GetEnabledCapabilities()
399+
if !enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
400+
break
401+
}
398402
machines, err = baremetal.Machines(clusterID.InfraID, ic, &pool, "master", masterUserDataSecretName)
399403
if err != nil {
400404
return errors.Wrap(err, "failed to create master machine objects")

pkg/asset/machines/worker.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -501,15 +501,18 @@ func (w *Worker) GenerateWithContext(ctx context.Context, dependencies asset.Par
501501
mpool.Set(pool.Platform.BareMetal)
502502
pool.Platform.BareMetal = &mpool
503503

504-
// Use managed user data secret, since images used by MachineSet
505-
// are always up to date
506-
workerUserDataSecretName = "worker-user-data-managed"
507-
sets, err := baremetal.MachineSets(clusterID.InfraID, ic, &pool, "", "worker", workerUserDataSecretName)
508-
if err != nil {
509-
return errors.Wrap(err, "failed to create worker machine objects")
510-
}
511-
for _, set := range sets {
512-
machineSets = append(machineSets, set)
504+
enabledCaps := installConfig.Config.GetEnabledCapabilities()
505+
if enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
506+
// Use managed user data secret, since images used by MachineSet
507+
// are always up to date
508+
workerUserDataSecretName = "worker-user-data-managed"
509+
sets, err := baremetal.MachineSets(clusterID.InfraID, ic, &pool, "", "worker", workerUserDataSecretName)
510+
if err != nil {
511+
return errors.Wrap(err, "failed to create worker machine objects")
512+
}
513+
for _, set := range sets {
514+
machineSets = append(machineSets, set)
515+
}
513516
}
514517
case gcptypes.Name:
515518
mpool := defaultGCPMachinePoolPlatform(pool.Architecture)

pkg/types/baremetal/validation/platform.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -433,24 +433,19 @@ func ValidatePlatform(p *baremetal.Platform, agentBasedInstallation bool, n *typ
433433
}
434434
}
435435

436-
if !agentBasedInstallation && p.Hosts == nil {
436+
enabledCaps := c.GetEnabledCapabilities()
437+
if !agentBasedInstallation && enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) && p.Hosts == nil {
437438
allErrs = append(allErrs, field.Invalid(fldPath.Child("hosts"), p.Hosts, "bare metal hosts are missing"))
438439
}
439440

440441
if p.DefaultMachinePlatform != nil {
441442
allErrs = append(allErrs, ValidateMachinePool(p.DefaultMachinePlatform, fldPath.Child("defaultMachinePlatform"))...)
442443
}
443444

444-
if !agentBasedInstallation {
445-
if err := validateHostsCount(p.Hosts, c); err != nil {
446-
allErrs = append(allErrs, field.Required(fldPath.Child("Hosts"), err.Error()))
445+
if !agentBasedInstallation && enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
446+
if err := ValidateHosts(p, fldPath, c); err != nil {
447+
allErrs = append(allErrs, err...)
447448
}
448-
allErrs = append(allErrs, validateHostsWithoutBMC(p.Hosts, fldPath)...)
449-
allErrs = append(allErrs, validateBootMode(p.Hosts, fldPath.Child("Hosts"))...)
450-
allErrs = append(allErrs, validateRootDeviceHints(p.Hosts, fldPath.Child("Hosts"))...)
451-
allErrs = append(allErrs, validateNetworkConfig(p.Hosts, fldPath.Child("Hosts"))...)
452-
453-
allErrs = append(allErrs, validateHostsName(p.Hosts, fldPath.Child("Hosts"))...)
454449
}
455450

456451
if c.BareMetal.LoadBalancer != nil {
@@ -462,6 +457,22 @@ func ValidatePlatform(p *baremetal.Platform, agentBasedInstallation bool, n *typ
462457
return allErrs
463458
}
464459

460+
// ValidateHosts returns an error if the Hosts are not valid.
461+
func ValidateHosts(p *baremetal.Platform, fldPath *field.Path, c *types.InstallConfig) field.ErrorList {
462+
allErrs := field.ErrorList{}
463+
464+
if err := validateHostsCount(p.Hosts, c); err != nil {
465+
allErrs = append(allErrs, field.Required(fldPath.Child("Hosts"), err.Error()))
466+
}
467+
allErrs = append(allErrs, validateHostsWithoutBMC(p.Hosts, fldPath)...)
468+
allErrs = append(allErrs, validateBootMode(p.Hosts, fldPath.Child("Hosts"))...)
469+
allErrs = append(allErrs, validateRootDeviceHints(p.Hosts, fldPath.Child("Hosts"))...)
470+
allErrs = append(allErrs, validateNetworkConfig(p.Hosts, fldPath.Child("Hosts"))...)
471+
472+
allErrs = append(allErrs, validateHostsName(p.Hosts, fldPath.Child("Hosts"))...)
473+
return allErrs
474+
}
475+
465476
// validateLoadBalancer returns an error if the load balancer is not valid.
466477
func validateLoadBalancer(lbType configv1.PlatformLoadBalancerType) bool {
467478
switch lbType {

pkg/types/baremetal/validation/platform_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ func TestValidatePlatform(t *testing.T) {
5151
Hosts().build(),
5252
expected: "bare metal hosts are missing",
5353
},
54+
{
55+
name: "no_hosts_machineapi_disabled",
56+
config: installConfig().
57+
Capabilities(types.Capabilities{BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetNone,
58+
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{configv1.ClusterVersionCapabilityIngress,
59+
configv1.ClusterVersionCapabilityBaremetal}}).
60+
BareMetalPlatform(
61+
platform().Hosts()).build(),
62+
},
5463
{
5564
name: "toofew_masters_norole",
5665
config: installConfig().
@@ -1004,6 +1013,11 @@ func (icb *installConfigBuilder) BareMetalPlatform(builder *platformBuilder) *in
10041013
return icb
10051014
}
10061015

1016+
func (icb *installConfigBuilder) Capabilities(capabilities types.Capabilities) *installConfigBuilder {
1017+
icb.InstallConfig.Capabilities = &capabilities
1018+
return icb
1019+
}
1020+
10071021
func (icb *installConfigBuilder) FeatureSet(value configv1.FeatureSet) *installConfigBuilder {
10081022
icb.InstallConfig.FeatureSet = value
10091023
return icb

pkg/types/installconfig.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/sirupsen/logrus"
88
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
"k8s.io/apimachinery/pkg/util/sets"
910

1011
configv1 "github.com/openshift/api/config/v1"
1112
features "github.com/openshift/api/features"
@@ -520,6 +521,32 @@ type Capabilities struct {
520521
AdditionalEnabledCapabilities []configv1.ClusterVersionCapability `json:"additionalEnabledCapabilities,omitempty"`
521522
}
522523

524+
// GetEnabledCapabilities returns a set of enabled ClusterVersionCapabilities.
525+
func (c *InstallConfig) GetEnabledCapabilities() sets.Set[configv1.ClusterVersionCapability] {
526+
enabledCaps := sets.Set[configv1.ClusterVersionCapability]{}
527+
if c.Capabilities == nil || c.Capabilities.BaselineCapabilitySet == "" {
528+
// when Capabilities and/or BaselineCapabilitySet is not specified, default is vCurrent
529+
baseSet := configv1.ClusterVersionCapabilitySets[configv1.ClusterVersionCapabilitySetCurrent]
530+
for _, cap := range baseSet {
531+
enabledCaps.Insert(cap)
532+
}
533+
}
534+
if c.Capabilities != nil {
535+
if c.Capabilities.BaselineCapabilitySet != "" {
536+
baseSet := configv1.ClusterVersionCapabilitySets[c.Capabilities.BaselineCapabilitySet]
537+
for _, cap := range baseSet {
538+
enabledCaps.Insert(cap)
539+
}
540+
}
541+
if c.Capabilities.AdditionalEnabledCapabilities != nil {
542+
for _, cap := range c.Capabilities.AdditionalEnabledCapabilities {
543+
enabledCaps.Insert(cap)
544+
}
545+
}
546+
}
547+
return enabledCaps
548+
}
549+
523550
// WorkerMachinePool retrieves the worker MachinePool from InstallConfig.Compute
524551
func (c *InstallConfig) WorkerMachinePool() *MachinePool {
525552
for _, machinePool := range c.Compute {

pkg/types/validation/installconfig.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ func ValidateInstallConfig(c *types.InstallConfig, usingAgentMethod bool) field.
200200

201201
if c.Capabilities.BaselineCapabilitySet == configv1.ClusterVersionCapabilitySetNone {
202202
enabledCaps := sets.New[configv1.ClusterVersionCapability](c.Capabilities.AdditionalEnabledCapabilities...)
203-
if enabledCaps.Has(configv1.ClusterVersionCapabilityBaremetal) && !enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
203+
if enabledCaps.Has(configv1.ClusterVersionCapabilityMarketplace) && !enabledCaps.Has(configv1.ClusterVersionCapabilityOperatorLifecycleManager) {
204204
allErrs = append(allErrs, field.Invalid(field.NewPath("additionalEnabledCapabilities"), c.Capabilities.AdditionalEnabledCapabilities,
205-
"the baremetal capability requires the MachineAPI capability"))
205+
"the marketplace capability requires the OperatorLifecycleManager capability"))
206206
}
207207
if c.Platform.BareMetal != nil && !enabledCaps.Has(configv1.ClusterVersionCapabilityBaremetal) {
208208
allErrs = append(allErrs, field.Invalid(field.NewPath("additionalEnabledCapabilities"), c.Capabilities.AdditionalEnabledCapabilities,

pkg/types/validation/installconfig_test.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,8 @@ func TestValidateInstallConfig(t *testing.T) {
683683
name: "valid baremetal platform",
684684
installConfig: func() *types.InstallConfig {
685685
c := validInstallConfig()
686+
c.Capabilities = &types.Capabilities{BaselineCapabilitySet: "v4.11"}
687+
c.Capabilities.AdditionalEnabledCapabilities = append(c.Capabilities.AdditionalEnabledCapabilities, configv1.ClusterVersionCapabilityIngress, configv1.ClusterVersionCapabilityCloudCredential, configv1.ClusterVersionCapabilityCloudControllerManager, configv1.ClusterVersionCapabilityOperatorLifecycleManager)
686688
c.Platform = types.Platform{
687689
BareMetal: validBareMetalPlatform(),
688690
}
@@ -1426,6 +1428,7 @@ func TestValidateInstallConfig(t *testing.T) {
14261428
installConfig: func() *types.InstallConfig {
14271429
c := validInstallConfig()
14281430
c.Platform = types.Platform{BareMetal: validBareMetalPlatform()}
1431+
c.Capabilities = &types.Capabilities{BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetCurrent}
14291432
c.CredentialsMode = types.PassthroughCredentialsMode
14301433
return c
14311434
}(),
@@ -1548,16 +1551,6 @@ func TestValidateInstallConfig(t *testing.T) {
15481551
}(),
15491552
expectedError: `additionalEnabledCapabilities: Invalid value: \[\]v1.ClusterVersionCapability{"marketplace"}: the marketplace capability requires the OperatorLifecycleManager capability`,
15501553
},
1551-
{
1552-
name: "invalid capability baremetal specified without MachineAPI",
1553-
installConfig: func() *types.InstallConfig {
1554-
c := validInstallConfig()
1555-
c.Capabilities = &types.Capabilities{BaselineCapabilitySet: "None",
1556-
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal"}}
1557-
return c
1558-
}(),
1559-
expectedError: `additionalEnabledCapabilities: Invalid value: \[\]v1.ClusterVersionCapability{"baremetal"}: the baremetal capability requires the MachineAPI capability`,
1560-
},
15611554
{
15621555
name: "valid additional enabled capability specified",
15631556
installConfig: func() *types.InstallConfig {
@@ -2201,16 +2194,15 @@ func TestValidateInstallConfig(t *testing.T) {
22012194
expectedError: "featureGates: Forbidden: featureGates can only be used with the CustomNoUpgrade feature set",
22022195
},
22032196
{
2204-
name: "return error when MAPI disabled w/o baremetal with baseline none",
2197+
name: "valid disabled MAPI with baseline none and baremetal enabled",
22052198
installConfig: func() *types.InstallConfig {
22062199
c := validInstallConfig()
22072200
c.Capabilities = &types.Capabilities{
22082201
BaselineCapabilitySet: configv1.ClusterVersionCapabilitySetNone,
2209-
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{configv1.ClusterVersionCapabilityBaremetal},
2202+
AdditionalEnabledCapabilities: []configv1.ClusterVersionCapability{configv1.ClusterVersionCapabilityBaremetal, configv1.ClusterVersionCapabilityIngress, configv1.ClusterVersionCapabilityCloudCredential, configv1.ClusterVersionCapabilityCloudControllerManager},
22102203
}
22112204
return c
22122205
}(),
2213-
expectedError: `the baremetal capability requires the MachineAPI capability`,
22142206
},
22152207
{
22162208
name: "valid disabled MAPI capability configuration",

0 commit comments

Comments
 (0)