mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 06:46:36 +01:00
Added support for platform None in TNA clusters
This commit is contained in:
@@ -31,6 +31,7 @@ import (
|
|||||||
"github.com/openshift/installer/pkg/asset/rhcos"
|
"github.com/openshift/installer/pkg/asset/rhcos"
|
||||||
"github.com/openshift/installer/pkg/types"
|
"github.com/openshift/installer/pkg/types"
|
||||||
baremetaltypes "github.com/openshift/installer/pkg/types/baremetal"
|
baremetaltypes "github.com/openshift/installer/pkg/types/baremetal"
|
||||||
|
nonetypes "github.com/openshift/installer/pkg/types/none"
|
||||||
ibmcloudapi "github.com/openshift/machine-api-provider-ibmcloud/pkg/apis"
|
ibmcloudapi "github.com/openshift/machine-api-provider-ibmcloud/pkg/apis"
|
||||||
ibmcloudprovider "github.com/openshift/machine-api-provider-ibmcloud/pkg/apis/ibmcloudprovider/v1"
|
ibmcloudprovider "github.com/openshift/machine-api-provider-ibmcloud/pkg/apis/ibmcloudprovider/v1"
|
||||||
)
|
)
|
||||||
@@ -115,8 +116,8 @@ func (m *Arbiter) Generate(ctx context.Context, dependencies asset.Parents) erro
|
|||||||
if ic.Arbiter == nil {
|
if ic.Arbiter == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ic.Platform.Name() != baremetaltypes.Name {
|
if ic.Platform.Name() != baremetaltypes.Name && ic.Platform.Name() != nonetypes.Name {
|
||||||
return fmt.Errorf("only BareMetal platform is supported for Arbiter deployments")
|
return fmt.Errorf("only BareMetal and None platforms are supported for Arbiter deployments")
|
||||||
}
|
}
|
||||||
|
|
||||||
pool := *ic.Arbiter
|
pool := *ic.Arbiter
|
||||||
@@ -125,43 +126,47 @@ func (m *Arbiter) Generate(ctx context.Context, dependencies asset.Parents) erro
|
|||||||
var ipClaims []ipamv1.IPAddressClaim
|
var ipClaims []ipamv1.IPAddressClaim
|
||||||
var ipAddrs []ipamv1.IPAddress
|
var ipAddrs []ipamv1.IPAddress
|
||||||
|
|
||||||
mpool := defaultBareMetalMachinePoolPlatform()
|
|
||||||
mpool.Set(ic.Platform.BareMetal.DefaultMachinePlatform)
|
|
||||||
mpool.Set(pool.Platform.BareMetal)
|
|
||||||
pool.Platform.BareMetal = &mpool
|
|
||||||
|
|
||||||
// Use managed user data secret, since we always have up to date images
|
// Use managed user data secret, since we always have up to date images
|
||||||
// available in the cluster
|
// available in the cluster
|
||||||
arbiterUserDataSecretName := "arbiter-user-data-managed" // #nosec G101
|
arbiterUserDataSecretName := "arbiter-user-data-managed" // #nosec G101
|
||||||
enabledCaps := installConfig.Config.GetEnabledCapabilities()
|
|
||||||
if enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
|
|
||||||
machines, err = baremetal.Machines(clusterID.InfraID, ic, &pool, "arbiter", arbiterUserDataSecretName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create arbiter machine objects: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hostSettings, err := baremetal.ArbiterHosts(ic, machines, arbiterUserDataSecretName)
|
// BareMetal-specific: configure machine pool and generate Machine API objects
|
||||||
if err != nil {
|
if ic.Platform.BareMetal != nil {
|
||||||
return fmt.Errorf("failed to assemble host data: %w", err)
|
mpool := defaultBareMetalMachinePoolPlatform()
|
||||||
}
|
mpool.Set(ic.Platform.BareMetal.DefaultMachinePlatform)
|
||||||
|
mpool.Set(pool.Platform.BareMetal)
|
||||||
|
pool.Platform.BareMetal = &mpool
|
||||||
|
|
||||||
hosts, err := createHostAssetFiles(hostSettings.Hosts, arbiterHostFileName)
|
enabledCaps := installConfig.Config.GetEnabledCapabilities()
|
||||||
if err != nil {
|
if enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) {
|
||||||
return err
|
machines, err = baremetal.Machines(clusterID.InfraID, ic, &pool, "arbiter", arbiterUserDataSecretName)
|
||||||
}
|
if err != nil {
|
||||||
m.HostFiles = append(m.HostFiles, hosts...)
|
return fmt.Errorf("failed to create arbiter machine objects: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
secrets, err := createSecretAssetFiles(hostSettings.Secrets, arbiterSecretFileName)
|
hostSettings, err := baremetal.ArbiterHosts(ic, machines, arbiterUserDataSecretName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to assemble host data: %w", err)
|
||||||
}
|
}
|
||||||
m.SecretFiles = append(m.SecretFiles, secrets...)
|
|
||||||
|
|
||||||
networkSecrets, err := createSecretAssetFiles(hostSettings.NetworkConfigSecrets, arbiterNetworkConfigSecretFileName)
|
hosts, err := createHostAssetFiles(hostSettings.Hosts, arbiterHostFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
m.HostFiles = append(m.HostFiles, hosts...)
|
||||||
|
|
||||||
|
secrets, err := createSecretAssetFiles(hostSettings.Secrets, arbiterSecretFileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.SecretFiles = append(m.SecretFiles, secrets...)
|
||||||
|
|
||||||
|
networkSecrets, err := createSecretAssetFiles(hostSettings.NetworkConfigSecrets, arbiterNetworkConfigSecretFileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.NetworkConfigSecretFiles = append(m.NetworkConfigSecretFiles, networkSecrets...)
|
||||||
}
|
}
|
||||||
m.NetworkConfigSecretFiles = append(m.NetworkConfigSecretFiles, networkSecrets...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := UserDataSecret(arbiterUserDataSecretName, mign.File.Data)
|
data, err := UserDataSecret(arbiterUserDataSecretName, mign.File.Data)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/openshift/installer/pkg/types"
|
"github.com/openshift/installer/pkg/types"
|
||||||
awstypes "github.com/openshift/installer/pkg/types/aws"
|
awstypes "github.com/openshift/installer/pkg/types/aws"
|
||||||
"github.com/openshift/installer/pkg/types/baremetal"
|
"github.com/openshift/installer/pkg/types/baremetal"
|
||||||
|
"github.com/openshift/installer/pkg/types/none"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestArbiterGenerateMachineConfigs(t *testing.T) {
|
func TestArbiterGenerateMachineConfigs(t *testing.T) {
|
||||||
@@ -219,7 +220,51 @@ func TestArbiterInstallOnlyForBaremetal(t *testing.T) {
|
|||||||
arbiter := &Arbiter{}
|
arbiter := &Arbiter{}
|
||||||
err := arbiter.Generate(context.Background(), parents)
|
err := arbiter.Generate(context.Background(), parents)
|
||||||
assert.NotNil(t, err, "expected arbiter generate to fail for non baremetal platforms")
|
assert.NotNil(t, err, "expected arbiter generate to fail for non baremetal platforms")
|
||||||
assert.Contains(t, err.Error(), "only BareMetal platform is supported for Arbiter deployments")
|
assert.Contains(t, err.Error(), "only BareMetal and None platforms are supported for Arbiter deployments")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArbiterInstallNonePlatform(t *testing.T) {
|
||||||
|
parents := asset.Parents{}
|
||||||
|
installConfig := installconfig.MakeAsset(
|
||||||
|
&types.InstallConfig{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-cluster",
|
||||||
|
},
|
||||||
|
SSHKey: "ssh-rsa: dummy-key",
|
||||||
|
BaseDomain: "test-domain",
|
||||||
|
Platform: types.Platform{
|
||||||
|
None: &none.Platform{},
|
||||||
|
},
|
||||||
|
Arbiter: &types.MachinePool{
|
||||||
|
Hyperthreading: types.HyperthreadingDisabled,
|
||||||
|
Replicas: ptr.To(int64(1)),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
parents.Add(
|
||||||
|
&installconfig.ClusterID{
|
||||||
|
UUID: "test-uuid",
|
||||||
|
InfraID: "test-infra-id",
|
||||||
|
},
|
||||||
|
installConfig,
|
||||||
|
rhcos.MakeAsset("test-image"),
|
||||||
|
(*rhcos.Release)(ptr.To("412.86.202208101040-0")),
|
||||||
|
&machine.Arbiter{
|
||||||
|
File: &asset.File{
|
||||||
|
Filename: "arbiter-ignition",
|
||||||
|
Data: []byte("test-ignition"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
arbiter := &Arbiter{}
|
||||||
|
err := arbiter.Generate(context.Background(), parents)
|
||||||
|
assert.Nil(t, err, "expected arbiter generate to succeed for None platform")
|
||||||
|
// For None platform, no Machine API objects or BareMetalHost CRs should be generated
|
||||||
|
assert.Equal(t, 0, len(arbiter.MachineFiles), "expected no machine files for None platform")
|
||||||
|
assert.Equal(t, 0, len(arbiter.HostFiles), "expected no host files for None platform")
|
||||||
|
assert.Equal(t, 0, len(arbiter.SecretFiles), "expected no secret files for None platform")
|
||||||
|
// MachineConfigs should still be generated (hyperthreading disabled + SSH key)
|
||||||
|
assert.Greater(t, len(arbiter.MachineConfigFiles), 0, "expected machine config files for None platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArbiterIsNotModified(t *testing.T) {
|
func TestArbiterIsNotModified(t *testing.T) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import (
|
|||||||
gcpvalidation "github.com/openshift/installer/pkg/types/gcp/validation"
|
gcpvalidation "github.com/openshift/installer/pkg/types/gcp/validation"
|
||||||
"github.com/openshift/installer/pkg/types/ibmcloud"
|
"github.com/openshift/installer/pkg/types/ibmcloud"
|
||||||
ibmcloudvalidation "github.com/openshift/installer/pkg/types/ibmcloud/validation"
|
ibmcloudvalidation "github.com/openshift/installer/pkg/types/ibmcloud/validation"
|
||||||
|
"github.com/openshift/installer/pkg/types/none"
|
||||||
"github.com/openshift/installer/pkg/types/nutanix"
|
"github.com/openshift/installer/pkg/types/nutanix"
|
||||||
nutanixvalidation "github.com/openshift/installer/pkg/types/nutanix/validation"
|
nutanixvalidation "github.com/openshift/installer/pkg/types/nutanix/validation"
|
||||||
"github.com/openshift/installer/pkg/types/openstack"
|
"github.com/openshift/installer/pkg/types/openstack"
|
||||||
@@ -778,8 +779,8 @@ func validateControlPlane(installConfig *types.InstallConfig, fldPath *field.Pat
|
|||||||
|
|
||||||
func validateArbiter(platform *types.Platform, arbiterPool, masterPool *types.MachinePool, fldPath *field.Path) field.ErrorList {
|
func validateArbiter(platform *types.Platform, arbiterPool, masterPool *types.MachinePool, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
if platform != nil && platform.BareMetal == nil {
|
if platform != nil && platform.BareMetal == nil && platform.None == nil {
|
||||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("platform"), platform.Name(), []string{baremetal.Name}))
|
allErrs = append(allErrs, field.NotSupported(fldPath.Child("platform"), platform.Name(), []string{baremetal.Name, none.Name}))
|
||||||
}
|
}
|
||||||
if arbiterPool.Name != types.MachinePoolArbiterRoleName {
|
if arbiterPool.Name != types.MachinePoolArbiterRoleName {
|
||||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("name"), arbiterPool.Name, []string{types.MachinePoolArbiterRoleName}))
|
allErrs = append(allErrs, field.NotSupported(fldPath.Child("name"), arbiterPool.Name, []string{types.MachinePoolArbiterRoleName}))
|
||||||
|
|||||||
@@ -3198,6 +3198,105 @@ func TestValidateTNF(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateArbiter(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
config *types.InstallConfig
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformNone().
|
||||||
|
MachinePoolArbiter(
|
||||||
|
machinePool().
|
||||||
|
Name("arbiter").
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(1).
|
||||||
|
CpReplicas(2).build(),
|
||||||
|
name: "valid_platform_none",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformBMWithHosts().
|
||||||
|
MachinePoolArbiter(
|
||||||
|
machinePool().
|
||||||
|
Name("arbiter").
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(1).
|
||||||
|
CpReplicas(2).build(),
|
||||||
|
name: "valid_platform_baremetal",
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformAWS().
|
||||||
|
MachinePoolArbiter(machinePool().
|
||||||
|
Name("arbiter").
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(1).
|
||||||
|
CpReplicas(2).build(),
|
||||||
|
name: "invalid_platform",
|
||||||
|
expected: `supported values: "baremetal", "none"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformNone().
|
||||||
|
MachinePoolArbiter(machinePool().
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(1).
|
||||||
|
CpReplicas(2).build(),
|
||||||
|
name: "invalid_arbiter_machine_pool_name",
|
||||||
|
expected: `arbiter.name: Unsupported value:`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformNone().
|
||||||
|
MachinePoolArbiter(machinePool().
|
||||||
|
Name("arbiter").
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(0).
|
||||||
|
CpReplicas(2).build(),
|
||||||
|
name: "invalid_arbiter_machine_pool_size",
|
||||||
|
expected: `arbiter.replicas: Invalid value:`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: installConfig().
|
||||||
|
PlatformNone().
|
||||||
|
MachinePoolArbiter(machinePool().
|
||||||
|
Name("arbiter").
|
||||||
|
Hyperthreading(types.HyperthreadingEnabled).
|
||||||
|
Architecture(types.ArchitectureAMD64)).
|
||||||
|
MachinePoolCP(machinePool()).
|
||||||
|
ArbiterReplicas(1).
|
||||||
|
CpReplicas(1).build(),
|
||||||
|
name: "invalid_master_machine_pool_size",
|
||||||
|
expected: `number of controlPlane replicas must be at least 2`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
err := validateArbiter(&tc.config.Platform, tc.config.Arbiter, tc.config.ControlPlane, field.NewPath("arbiter")).ToAggregate()
|
||||||
|
|
||||||
|
if tc.expected == "" {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
assert.Regexp(t, tc.expected, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type credentialBuilder struct {
|
type credentialBuilder struct {
|
||||||
types.Credential
|
types.Credential
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user