Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion pkg/types/baremetal/validation/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,28 @@ func validateOSImages(p *baremetal.Platform, fldPath *field.Path) field.ErrorLis
return platformErrs
}

func validateHostsCount(hosts []*baremetal.Host, installConfig *types.InstallConfig) error {

hostsNum := int64(len(hosts))
counter := int64(0)

for _, worker := range installConfig.Compute {
if worker.Replicas != nil {
counter += *worker.Replicas
}
}
if installConfig.ControlPlane != nil && installConfig.ControlPlane.Replicas != nil {
counter += *installConfig.ControlPlane.Replicas
}
if hostsNum < counter {
return fmt.Errorf("not enough hosts found (%v) to support all the configured ControlPlane and Compute replicas (%v)", hostsNum, counter)
}

return nil
}

// ValidatePlatform checks that the specified platform is valid.
func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field.Path) field.ErrorList {
func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field.Path, c *types.InstallConfig) field.ErrorList {
allErrs := field.ErrorList{}
if err := validate.URI(p.LibvirtURI); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("libvirtURI"), p.LibvirtURI, err.Error()))
Expand Down Expand Up @@ -238,6 +258,10 @@ func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field
allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapHostIP"), p.BootstrapProvisioningIP, err.Error()))
}

if err := validateHostsCount(p.Hosts, c); err != nil {
allErrs = append(allErrs, field.Required(fldPath.Child("Hosts"), err.Error()))
}

allErrs = append(allErrs, validateOSImages(p, fldPath)...)

allErrs = append(allErrs, validateHosts(p.Hosts, fldPath)...)
Expand Down
116 changes: 102 additions & 14 deletions pkg/types/baremetal/validation/platform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestValidatePlatform(t *testing.T) {

cases := []struct {
name string
config *types.InstallConfig
platform *baremetal.Platform
expected string
}{
Expand Down Expand Up @@ -218,61 +219,91 @@ func TestValidatePlatform(t *testing.T) {
name: "duplicate_bmc_address",
platform: platform().
Hosts(
host1().BMCAddress("ipmi://192.168.111.1").build(),
host2().BMCAddress("ipmi://192.168.111.1").build()).build(),
host1().BMCAddress("ipmi://192.168.111.1"),
host2().BMCAddress("ipmi://192.168.111.1")).build(),
expected: "baremetal.hosts\\[1\\].BMC.Address: Duplicate value: \"ipmi://192.168.111.1\"",
},
{
name: "bmc_address_required",
platform: platform().
Hosts(host1().BMCAddress("").build()).build(),
Hosts(host1().BMCAddress("")).build(),
expected: "baremetal.hosts\\[0\\].BMC.Address: Required value: missing Address",
},
{
name: "bmc_username_required",
platform: platform().
Hosts(host1().BMCUsername("").build()).build(),
Hosts(host1().BMCUsername("")).build(),
expected: "baremetal.hosts\\[0\\].BMC.Username: Required value: missing Username",
},
{
name: "bmc_password_required",
platform: platform().
Hosts(host1().BMCPassword("").build()).build(),
Hosts(host1().BMCPassword("")).build(),
expected: "baremetal.hosts\\[0\\].BMC.Password: Required value: missing Password",
},
{
name: "duplicate_host_name",
platform: platform().
Hosts(
host1().Name("host1").build(),
host2().Name("host1").build()).build(),
host1().Name("host1"),
host2().Name("host1")).build(),
expected: "baremetal.hosts\\[1\\].Name: Duplicate value: \"host1\"",
},
{
name: "duplicate_host_mac",
platform: platform().
Hosts(
host1().BootMACAddress("CA:FE:CA:FE:CA:FE").build(),
host2().BootMACAddress("CA:FE:CA:FE:CA:FE").build()).build(),
host1().BootMACAddress("CA:FE:CA:FE:CA:FE"),
host2().BootMACAddress("CA:FE:CA:FE:CA:FE")).build(),
expected: "baremetal.hosts\\[1\\].BootMACAddress: Duplicate value: \"CA:FE:CA:FE:CA:FE\"",
},
{
name: "missing_name",
platform: platform().
Hosts(host1().Name("").build()).build(),
Hosts(host1().Name("")).build(),
expected: "baremetal.hosts\\[0\\].Name: Required value: missing Name",
},
{
name: "missing_mac",
platform: platform().
Hosts(host1().BootMACAddress("").build()).build(),
Hosts(host1().BootMACAddress("")).build(),
expected: "baremetal.hosts\\[0\\].BootMACAddress: Required value: missing BootMACAddress",
},
{
name: "toofew_hosts",
config: installConfig().
BareMetalPlatform(
platform().Hosts(
host1())).
ControlPlane(
machinePool().Replicas(3)).
Compute(
machinePool().Replicas(2),
machinePool().Replicas(3)).build(),
expected: "baremetal.Hosts: Required value: not enough hosts found \\(1\\) to support all the configured ControlPlane and Compute replicas \\(8\\)",
},
{
name: "enough_hosts",
config: installConfig().
BareMetalPlatform(
platform().Hosts(
host1(),
host2())).
ControlPlane(
machinePool().Replicas(2)).build(),
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
err := ValidatePlatform(tc.platform, network(), field.NewPath("baremetal")).ToAggregate()
//Build default wrapping installConfig
if tc.config == nil {
tc.config = installConfig().build()
tc.config.BareMetal = tc.platform
}

err := ValidatePlatform(tc.config.BareMetal, network(), field.NewPath("baremetal"), tc.config).ToAggregate()

if tc.expected == "" {
assert.NoError(t, err)
} else {
Expand Down Expand Up @@ -413,8 +444,11 @@ func (pb *platformBuilder) IngressVIP(value string) *platformBuilder {
return pb
}

func (pb *platformBuilder) Hosts(value ...*baremetal.Host) *platformBuilder {
pb.Platform.Hosts = value
func (pb *platformBuilder) Hosts(builders ...*hostBuilder) *platformBuilder {
pb.Platform.Hosts = nil
for _, builder := range builders {
pb.Platform.Hosts = append(pb.Platform.Hosts, builder.build())
}
return pb
}

Expand All @@ -441,3 +475,57 @@ func (pb *platformBuilder) ProvisioningNetworkInterface(value string) *platformB
func network() *types.Networking {
return &types.Networking{MachineNetwork: []types.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.111.0/24")}}}
}

type installConfigBuilder struct {
types.InstallConfig
}

func installConfig() *installConfigBuilder {
return &installConfigBuilder{
InstallConfig: types.InstallConfig{},
}
}

func (icb *installConfigBuilder) build() *types.InstallConfig {
return &icb.InstallConfig
}

func (icb *installConfigBuilder) BareMetalPlatform(builder *platformBuilder) *installConfigBuilder {
icb.InstallConfig.Platform = types.Platform{
BareMetal: builder.build(),
}
return icb
}

func (icb *installConfigBuilder) ControlPlane(builder *machinePoolBuilder) *installConfigBuilder {
icb.InstallConfig.ControlPlane = builder.build()

return icb
}

func (icb *installConfigBuilder) Compute(builders ...*machinePoolBuilder) *installConfigBuilder {
icb.InstallConfig.Compute = nil
for _, builder := range builders {
icb.InstallConfig.Compute = append(icb.InstallConfig.Compute, *builder.build())
}
return icb
}

type machinePoolBuilder struct {
types.MachinePool
}

func machinePool() *machinePoolBuilder {
return &machinePoolBuilder{
MachinePool: types.MachinePool{},
}
}

func (mpb *machinePoolBuilder) build() *types.MachinePool {
return &mpb.MachinePool
}

func (mpb *machinePoolBuilder) Replicas(count int64) *machinePoolBuilder {
mpb.MachinePool.Replicas = &count
return mpb
}
2 changes: 1 addition & 1 deletion pkg/types/validation/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ func validatePlatform(platform *types.Platform, fldPath *field.Path, openStackVa
}
if platform.BareMetal != nil {
validate(baremetal.Name, platform.BareMetal, func(f *field.Path) field.ErrorList {
return baremetalvalidation.ValidatePlatform(platform.BareMetal, network, f)
return baremetalvalidation.ValidatePlatform(platform.BareMetal, network, f, c)
})
}
return allErrs
Expand Down
33 changes: 26 additions & 7 deletions pkg/types/validation/installconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,32 @@ func validBareMetalPlatform() *baremetal.Platform {
ProvisioningNetworkCIDR: ipnet.MustParseCIDR("192.168.111.0/24"),
BootstrapProvisioningIP: "192.168.111.1",
ClusterProvisioningIP: "192.168.111.2",
Hosts: []*baremetal.Host{},
ExternalBridge: iface[0].Name,
ProvisioningBridge: iface[0].Name,
DefaultMachinePlatform: &baremetal.MachinePool{},
APIVIP: "10.0.0.5",
IngressVIP: "10.0.0.4",
DNSVIP: "10.0.0.2",
Hosts: []*baremetal.Host{
{
Name: "host1",
BootMACAddress: "CA:FE:CA:FE:00:00",
BMC: baremetal.BMC{
Username: "root",
Password: "password",
Address: "ipmi://192.168.111.1",
},
},
{
Name: "host2",
BootMACAddress: "CA:FE:CA:FE:00:01",
BMC: baremetal.BMC{
Username: "root",
Password: "password",
Address: "ipmi://192.168.111.2",
},
},
},
ExternalBridge: iface[0].Name,
ProvisioningBridge: iface[0].Name,
DefaultMachinePlatform: &baremetal.MachinePool{},
APIVIP: "10.0.0.5",
IngressVIP: "10.0.0.4",
DNSVIP: "10.0.0.2",
}
}

Expand Down