diff --git a/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template b/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template index 8e795b3e50a..ed2b588ca16 100755 --- a/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template +++ b/data/data/bootstrap/baremetal/files/usr/local/bin/startironic.sh.template @@ -11,6 +11,10 @@ COREOS_DOWNLOADER_IMAGE=$(image_for ironic-machine-os-downloader || image_for ir # This image is templated in via the installer pkg/asset/ignition/bootstrap/bootstrap.go RHCOS_BOOT_IMAGE_URL="{{.BootImage}}" +# This DHCP range is used by dnsmasq to serve DHCP to the cluster. If empty +# dnsmasq will only serve TFTP, and DHCP will be disabled. +DHCP_RANGE="{{.PlatformData.BareMetal.ProvisioningDHCPRange}}" + # First we stop any previously started containers, because ExecStop only runs when the ExecStart process # e.g this script is still running, but we exit if *any* of the containers exits unexpectedly for name in ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb ipa-downloader coreos-downloader; do @@ -19,10 +23,9 @@ for name in ironic-api ironic-conductor ironic-inspector dnsmasq httpd mariadb i done # Start the provisioning nic if not already started -# Note removal of the hard-coded subnet tracked via https://github.com/openshift/installer/issues/2091 PROVISIONING_NIC=ens4 if ! nmcli -t device | grep "$PROVISIONING_NIC:ethernet:connected:provisioning"; then - nmcli c add type ethernet ifname $PROVISIONING_NIC con-name provisioning ip4 172.22.0.2/24 gw4 172.22.0.1 + nmcli c add type ethernet ifname $PROVISIONING_NIC con-name provisioning {{ if .PlatformData.BareMetal.ProvisioningIPv6 }} ip6 {{ else }} ip4 {{ end }} {{.PlatformData.BareMetal.ProvisioningIP}}/{{.PlatformData.BareMetal.ProvisioningCIDR}} nmcli c up provisioning fi @@ -63,6 +66,7 @@ podman run -d --net host --privileged --name mariadb \ podman run -d --net host --privileged --name dnsmasq \ --env PROVISIONING_INTERFACE=$PROVISIONING_NIC \ + --env DHCP_RANGE=$DHCP_RANGE \ -v $IRONIC_SHARED_VOLUME:/shared:z --entrypoint /bin/rundnsmasq ${IRONIC_IMAGE} podman run -d --net host --privileged --name httpd \ diff --git a/docs/user/metal/install_ipi.md b/docs/user/metal/install_ipi.md index 277ec116b2f..8256aa9f653 100644 --- a/docs/user/metal/install_ipi.md +++ b/docs/user/metal/install_ipi.md @@ -46,10 +46,18 @@ purposes: * `*.apps..` - pointing to the Ingress VIP * **NIC #2 - Provisioning Network** - * A private, non-routed network, used for PXE based provisioning. - * DHCP is automated for this network. - * Addressing for this network is currently hard coded as `172.22.0.0/24`, but - will be made configurable in the future. + * A private network used for PXE based provisioning. + * DHCP is automated for this network by default, to rely on external + DHCP, set the platform's `provisioningDHCPExternal` option to `true` + * Addressing for this network defaults to `172.22.0.0/24`, but is + configurable by setting the `provisioningNetworkCIDR` option. + * Two IP's are required to be available for use, one for the bootstrap + host, and one as a provisioning IP in the running cluster. By + default, these are the 2nd and 3rd addresses in the + `provisioningNetworkCIDR` (e.g. 172.22.0.2, and 172.22.0.3). + * To specify the name of the provisioning network interface, + set the `provisioningNetworkInterface` option. This is the network interface + on a master that is connected to the provisioning network. * **Out-of-band Management Network** * Servers will typically have an additional NIC used by the onboard diff --git a/pkg/asset/ignition/bootstrap/baremetal/template.go b/pkg/asset/ignition/bootstrap/baremetal/template.go new file mode 100644 index 00000000000..526481e64f0 --- /dev/null +++ b/pkg/asset/ignition/bootstrap/baremetal/template.go @@ -0,0 +1,39 @@ +package baremetal + +import ( + "github.com/openshift/installer/pkg/types/baremetal" +) + +// TemplateData holds data specific to templates used for the baremetal platform. +type TemplateData struct { + // ProvisioningIP holds the IP the bootstrap node will use to service Ironic, TFTP, etc. + ProvisioningIP string + + // ProvisioningIPv6 determines if we are using IPv6 or not. + ProvisioningIPv6 bool + + // ProvisioningCIDR has the integer CIDR notation, e.g. 255.255.255.0 should be "24" + ProvisioningCIDR int + + // ProvisioningDHCPRange has the DHCP range, if DHCP is not external. Otherwise it + // should be blank. + ProvisioningDHCPRange string +} + +// GetTemplateData returns platform-specific data for bootstrap templates. +func GetTemplateData(config *baremetal.Platform) *TemplateData { + var templateData TemplateData + + templateData.ProvisioningIP = config.BootstrapProvisioningIP + + cidr, _ := config.ProvisioningNetworkCIDR.Mask.Size() + templateData.ProvisioningCIDR = cidr + + templateData.ProvisioningIPv6 = config.ProvisioningNetworkCIDR.IP.To4() == nil + + if !config.ProvisioningDHCPExternal { + templateData.ProvisioningDHCPRange = config.ProvisioningDHCPRange + } + + return &templateData +} diff --git a/pkg/asset/ignition/bootstrap/baremetal/template_test.go b/pkg/asset/ignition/bootstrap/baremetal/template_test.go new file mode 100644 index 00000000000..2e2d837dbb0 --- /dev/null +++ b/pkg/asset/ignition/bootstrap/baremetal/template_test.go @@ -0,0 +1,39 @@ +package baremetal + +import ( + "github.com/openshift/installer/pkg/ipnet" + "github.com/openshift/installer/pkg/types/baremetal" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestTemplatingIPv4(t *testing.T) { + bareMetalConfig := baremetal.Platform{ + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningDHCPExternal: false, + ProvisioningDHCPRange: "172.22.0.10,172.22.0.100", + } + + result := GetTemplateData(&bareMetalConfig) + + assert.Equal(t, result.ProvisioningDHCPRange, "172.22.0.10,172.22.0.100") + assert.Equal(t, result.ProvisioningCIDR, 24) + assert.Equal(t, result.ProvisioningIPv6, false) + assert.Equal(t, result.ProvisioningIP, "172.22.0.2") +} + +func TestTemplatingIPv6(t *testing.T) { + bareMetalConfig := baremetal.Platform{ + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("fd2e:6f44:5dd8:b856::0/64"), + BootstrapProvisioningIP: "fd2e:6f44:5dd8:b856::2", + ProvisioningDHCPExternal: true, + } + + result := GetTemplateData(&bareMetalConfig) + + assert.Equal(t, result.ProvisioningDHCPRange, "") + assert.Equal(t, result.ProvisioningCIDR, 64) + assert.Equal(t, result.ProvisioningIPv6, true) + assert.Equal(t, result.ProvisioningIP, "fd2e:6f44:5dd8:b856::2") +} diff --git a/pkg/asset/ignition/bootstrap/bootstrap.go b/pkg/asset/ignition/bootstrap/bootstrap.go index 14b53ccd2dd..e3ac199d286 100644 --- a/pkg/asset/ignition/bootstrap/bootstrap.go +++ b/pkg/asset/ignition/bootstrap/bootstrap.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "github.com/openshift/installer/pkg/asset/ignition/bootstrap/baremetal" "io" "io/ioutil" "os" @@ -30,6 +31,7 @@ import ( "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/asset/tls" "github.com/openshift/installer/pkg/types" + baremetaltypes "github.com/openshift/installer/pkg/types/baremetal" ) const ( @@ -50,6 +52,13 @@ type bootstrapTemplateData struct { Registries []sysregistriesv2.Registry BootImage string ClusterDomain string + PlatformData platformTemplateData +} + +// platformTemplateData is the data to use to replace values in bootstrap +// template files that are specific to one platform. +type platformTemplateData struct { + BareMetal *baremetal.TemplateData } // Bootstrap is an asset that generates the ignition config for bootstrap nodes. @@ -223,6 +232,14 @@ func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseI registries = append(registries, registry) } + // Generate platform-specific baremetal data + var platformData platformTemplateData + + switch installConfig.Platform.Name() { + case baremetaltypes.Name: + platformData.BareMetal = baremetal.GetTemplateData(installConfig.Platform.BareMetal) + } + return &bootstrapTemplateData{ AdditionalTrustBundle: installConfig.AdditionalTrustBundle, FIPS: installConfig.FIPS, @@ -233,6 +250,7 @@ func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseI Registries: registries, BootImage: string(*rhcosImage), ClusterDomain: installConfig.ClusterDomain(), + PlatformData: platformData, }, nil } diff --git a/pkg/types/baremetal/defaults/platform.go b/pkg/types/baremetal/defaults/platform.go index 47e03cc3e50..b5abedab538 100644 --- a/pkg/types/baremetal/defaults/platform.go +++ b/pkg/types/baremetal/defaults/platform.go @@ -2,36 +2,64 @@ package defaults import ( "fmt" + "github.com/openshift/installer/pkg/ipnet" "net" + "github.com/apparentlymart/go-cidr/cidr" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/baremetal" ) // Defaults for the baremetal platform. const ( - LibvirtURI = "qemu:///system" - BootstrapProvisioningIP = "172.22.0.2" - ClusterProvisioningIP = "172.22.0.3" - ExternalBridge = "baremetal" - ProvisioningBridge = "provisioning" - HardwareProfile = "default" - APIVIP = "" - IngressVIP = "" + LibvirtURI = "qemu:///system" + ProvisioningNetworkCIDR = "172.22.0.0/24" + ExternalBridge = "baremetal" + ProvisioningBridge = "provisioning" + ProvisioningNetworkInterface = "ens3" + HardwareProfile = "default" + APIVIP = "" + IngressVIP = "" ) +// Wrapper for net.LookupHost so we can override in the test +var lookupHost = func(host string) (addrs []string, err error) { + return net.LookupHost(host) +} + // SetPlatformDefaults sets the defaults for the platform. func SetPlatformDefaults(p *baremetal.Platform, c *types.InstallConfig) { if p.LibvirtURI == "" { p.LibvirtURI = LibvirtURI } + if p.ProvisioningNetworkCIDR == nil { + p.ProvisioningNetworkCIDR = ipnet.MustParseCIDR(ProvisioningNetworkCIDR) + } + + // If the user doesn't provide an explicit DHCP range, and DHCP is not + // disabled, then we set a default value from the 10th to 100th + // address in the network. + if !p.ProvisioningDHCPExternal && p.ProvisioningDHCPRange == "" { + startIP, _ := cidr.Host(&p.ProvisioningNetworkCIDR.IPNet, 10) + endIP, _ := cidr.Host(&p.ProvisioningNetworkCIDR.IPNet, 100) + p.ProvisioningDHCPRange = fmt.Sprintf("%s,%s", startIP, endIP) + } + if p.BootstrapProvisioningIP == "" { - p.BootstrapProvisioningIP = BootstrapProvisioningIP + // Default to the second address in provisioning network, e.g 172.22.0.2 + ip, err := cidr.Host(&p.ProvisioningNetworkCIDR.IPNet, 2) + if err == nil { + p.BootstrapProvisioningIP = ip.String() + } } if p.ClusterProvisioningIP == "" { - p.ClusterProvisioningIP = ClusterProvisioningIP + // Default to the third address in provisioning network, e.g 172.22.0.3 + ip, err := cidr.Host(&p.ProvisioningNetworkCIDR.IPNet, 3) + if err == nil { + p.ClusterProvisioningIP = ip.String() + } } if p.ExternalBridge == "" { @@ -42,6 +70,10 @@ func SetPlatformDefaults(p *baremetal.Platform, c *types.InstallConfig) { p.ProvisioningBridge = ProvisioningBridge } + if p.ProvisioningNetworkInterface == "" { + p.ProvisioningNetworkInterface = ProvisioningNetworkInterface + } + for _, host := range p.Hosts { if host.HardwareProfile == "" { host.HardwareProfile = HardwareProfile @@ -50,7 +82,7 @@ func SetPlatformDefaults(p *baremetal.Platform, c *types.InstallConfig) { if p.APIVIP == APIVIP { // This name should resolve to exactly one address - vip, err := net.LookupHost("api." + c.ClusterDomain()) + vip, err := lookupHost("api." + c.ClusterDomain()) if err != nil { // This will fail validation and abort the install p.APIVIP = fmt.Sprintf("DNS lookup failure: %s", err.Error()) @@ -61,7 +93,7 @@ func SetPlatformDefaults(p *baremetal.Platform, c *types.InstallConfig) { if p.IngressVIP == IngressVIP { // This name should resolve to exactly one address - vip, err := net.LookupHost("test.apps." + c.ClusterDomain()) + vip, err := lookupHost("test.apps." + c.ClusterDomain()) if err != nil { // This will fail validation and abort the install p.IngressVIP = fmt.Sprintf("DNS lookup failure: %s", err.Error()) diff --git a/pkg/types/baremetal/defaults/platform_test.go b/pkg/types/baremetal/defaults/platform_test.go new file mode 100644 index 00000000000..52de957ccec --- /dev/null +++ b/pkg/types/baremetal/defaults/platform_test.go @@ -0,0 +1,120 @@ +package defaults + +import ( + "errors" + "github.com/openshift/installer/pkg/ipnet" + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/baremetal" +) + +const testClusterName = "test-cluster" + +func TestSetPlatformDefaults(t *testing.T) { + // Stub the call to net.LookupHost + lookupHost = func(host string) (addrs []string, err error) { + if host == "api.test-cluster.test" { + ips := []string{"192.168.111.2"} + return ips, nil + } else if host == "test.apps.test-cluster.test" { + ips := []string{"192.168.111.3"} + return ips, nil + } else { + return nil, errors.New("Unknown Host " + host) + } + } + + cases := []struct { + name string + platform *baremetal.Platform + expected *baremetal.Platform + }{ + { + name: "default_empty", + platform: &baremetal.Platform{}, + expected: &baremetal.Platform{ + LibvirtURI: "qemu:///system", + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "baremetal", + ProvisioningBridge: "provisioning", + APIVIP: "192.168.111.2", + IngressVIP: "192.168.111.3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ProvisioningDHCPRange: "172.22.0.10,172.22.0.100", + ProvisioningNetworkInterface: "ens3", + }, + }, + { + name: "alternate_cidr", + platform: &baremetal.Platform{ + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.23.0.0/24"), + }, + expected: &baremetal.Platform{ + LibvirtURI: "qemu:///system", + ClusterProvisioningIP: "172.23.0.3", + BootstrapProvisioningIP: "172.23.0.2", + ExternalBridge: "baremetal", + ProvisioningBridge: "provisioning", + APIVIP: "192.168.111.2", + IngressVIP: "192.168.111.3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.23.0.0/24"), + ProvisioningDHCPRange: "172.23.0.10,172.23.0.100", + ProvisioningNetworkInterface: "ens3", + }, + }, + { + name: "alternate_cidr_ipv6", + platform: &baremetal.Platform{ + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("fd2e:6f44:5dd8:b856::/64"), + }, + expected: &baremetal.Platform{ + LibvirtURI: "qemu:///system", + ClusterProvisioningIP: "fd2e:6f44:5dd8:b856::3", + BootstrapProvisioningIP: "fd2e:6f44:5dd8:b856::2", + ExternalBridge: "baremetal", + ProvisioningBridge: "provisioning", + APIVIP: "192.168.111.2", + IngressVIP: "192.168.111.3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("fd2e:6f44:5dd8:b856::/64"), + ProvisioningDHCPRange: "fd2e:6f44:5dd8:b856::a,fd2e:6f44:5dd8:b856::64", + ProvisioningNetworkInterface: "ens3", + }, + }, + { + name: "alternate_cidr_dhcp_disabled", + platform: &baremetal.Platform{ + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.23.0.0/24"), + ProvisioningDHCPExternal: true, + }, + expected: &baremetal.Platform{ + LibvirtURI: "qemu:///system", + ClusterProvisioningIP: "172.23.0.3", + BootstrapProvisioningIP: "172.23.0.2", + ExternalBridge: "baremetal", + ProvisioningBridge: "provisioning", + APIVIP: "192.168.111.2", + IngressVIP: "192.168.111.3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.23.0.0/24"), + ProvisioningDHCPExternal: true, + ProvisioningNetworkInterface: "ens3", + }, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + ic := &types.InstallConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: testClusterName, + }, + BaseDomain: "test", + } + SetPlatformDefaults(tc.platform, ic) + assert.Equal(t, tc.expected, tc.platform, "unexpected platform") + }) + } +} diff --git a/pkg/types/baremetal/platform.go b/pkg/types/baremetal/platform.go index 84fad0fa96b..d7f4a3538f6 100644 --- a/pkg/types/baremetal/platform.go +++ b/pkg/types/baremetal/platform.go @@ -1,5 +1,9 @@ package baremetal +import ( + "github.com/openshift/installer/pkg/ipnet" +) + // BMC stores the information about a baremetal host's management controller. type BMC struct { Username string `json:"username"` @@ -40,10 +44,31 @@ type Platform struct { // +optional ExternalBridge string `json:"externalBridge,omitempty"` - // Provisioning bridge is used for provisioning nodes. + // Provisioning bridge is used for provisioning nodes, on the host that + // will run the bootstrap VM. // +optional ProvisioningBridge string `json:"provisioningBridge,omitempty"` + // ProvisioningNetworkInterface is the name of the network interface on a control plane + // baremetal host that is connected to the provisioning network. + ProvisioningNetworkInterface string `json:"provisioningNetworkInterface"` + + // ProvisioningNetworkCIDR defines the network to use for provisioning. + // +optional + ProvisioningNetworkCIDR *ipnet.IPNet `json:"provisioningNetworkCIDR,omitempty"` + + // ProvisioningDHCPExternal indicates that DHCP is provided by an external service, appropriately + // configured with next-server set to BootstrapProvisioningIP for the control plane, and + // ClusterProvisioningIP for workers. The default for this field is false, which means we will + // start and manage a DHCP server on the provisioning network. + // +optional + ProvisioningDHCPExternal bool `json:"provisioningDHCPExternal,omitempty"` + + // ProvisioningDHCPRange is used to provide DHCP services to hosts + // for provisioning. + // +optional + ProvisioningDHCPRange string `json:"provisioningDHCPRange,omitempty"` + // Hosts is the information needed to create the objects in Ironic. Hosts []*Host `json:"hosts"` diff --git a/pkg/types/baremetal/validation/platform.go b/pkg/types/baremetal/validation/platform.go index 41505bc50f5..e24dc3c3232 100644 --- a/pkg/types/baremetal/validation/platform.go +++ b/pkg/types/baremetal/validation/platform.go @@ -9,6 +9,7 @@ import ( "github.com/openshift/installer/pkg/types/baremetal" "github.com/openshift/installer/pkg/validate" "k8s.io/apimachinery/pkg/util/validation/field" + "strings" ) // dynamicValidator is a function that validates certain fields in the platform. @@ -71,10 +72,42 @@ func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningHostIP"), p.ClusterProvisioningIP, err.Error())) } + if p.ProvisioningNetworkCIDR != nil && !p.ProvisioningNetworkCIDR.Contains(net.ParseIP(p.ClusterProvisioningIP)) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterProvisioningIP"), p.ClusterProvisioningIP, fmt.Sprintf("%q is not in the provisioning network", p.ClusterProvisioningIP))) + } + if err := validate.IP(p.BootstrapProvisioningIP); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapProvisioningIP"), p.BootstrapProvisioningIP, err.Error())) } + if p.ProvisioningNetworkCIDR != nil && !p.ProvisioningNetworkCIDR.Contains(net.ParseIP(p.BootstrapProvisioningIP)) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapProvisioningIP"), p.BootstrapProvisioningIP, fmt.Sprintf("%q is not in the provisioning network", p.BootstrapProvisioningIP))) + } + + if p.ProvisioningDHCPRange != "" { + dhcpRange := strings.Split(p.ProvisioningDHCPRange, ",") + if len(dhcpRange) != 2 { + allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPRange"), p.ProvisioningDHCPRange, "provisioning dhcp range should be in format: start_ip,end_ip")) + } else { + for _, ip := range dhcpRange { + // Ensure IP is valid + if err := validate.IP(ip); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPRange"), p.ProvisioningDHCPRange, fmt.Sprintf("%s: %s", ip, err.Error()))) + } + + // Validate IP is in the provisioning network + if p.ProvisioningNetworkCIDR != nil && !p.ProvisioningNetworkCIDR.Contains(net.ParseIP(ip)) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPRange"), p.ProvisioningDHCPRange, fmt.Sprintf("%q is not in the provisioning network", ip))) + } + } + } + } + + // Make sure the provisioning interface is set. Very little we can do to validate this as it's not on this machine. + if p.ProvisioningNetworkInterface == "" { + allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningNetworkInterface"), p.ProvisioningNetworkInterface, "No baremetal provisioning network interface is configured.")) + } + if p.Hosts == nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("hosts"), p.Hosts, "bare metal hosts are missing")) } diff --git a/pkg/types/baremetal/validation/platform_test.go b/pkg/types/baremetal/validation/platform_test.go index 0f38dc1a7be..2a91cf9be12 100644 --- a/pkg/types/baremetal/validation/platform_test.go +++ b/pkg/types/baremetal/validation/platform_test.go @@ -38,47 +38,146 @@ func TestValidatePlatform(t *testing.T) { { name: "valid", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + ProvisioningNetworkInterface: "ens3", }, network: network, }, + { + name: "valid_ipv6_provisioning", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("fd2e:6f44:5dd8:b856::/64"), + ClusterProvisioningIP: "fd2e:6f44:5dd8:b856::3", + BootstrapProvisioningIP: "fd2e:6f44:5dd8:b856::2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + ProvisioningNetworkInterface: "ens3", + }, + network: network, + }, + { name: "valid_with_os_image_overrides", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + ProvisioningNetworkInterface: "ens3", + }, + network: network, + }, + { + name: "valid_provisioningDHCPRange", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningDHCPRange: "172.22.0.10,172.22.0.50", + ProvisioningNetworkInterface: "ens3", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, }, + { + name: "invalid_provisioningDHCPRange_missing_pair", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningDHCPRange: "172.22.0.10,", + ProvisioningNetworkInterface: "ens3", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + }, + network: network, + expected: "provisioningDHCPRange: Invalid value: \"172.22.0.10,\": : \"\" is not a valid IP", + }, + { + name: "invalid_provisioningDHCPRange_not_a_range", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningDHCPRange: "172.22.0.19", + ProvisioningNetworkInterface: "ens3", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + }, + network: network, + expected: "Invalid value: \"172.22.0.19\": provisioning dhcp range should be in format: start_ip,end_ip", + }, + { + name: "invalid_provisioningDHCPRange_wrong_CIDR", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningNetworkInterface: "ens3", + ProvisioningDHCPRange: "192.168.128.1,172.22.0.100", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + }, + network: network, + expected: "Invalid value: \"192.168.128.1,172.22.0.100\": \"192.168.128.1\" is not in the provisioning network", + }, { name: "invalid_apivip", platform: &baremetal.Platform{ - APIVIP: "192.168.222.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.222.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ProvisioningNetworkInterface: "ens3", + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"192.168.222.2\": the virtual IP is expected to be in one of the machine networks", @@ -86,15 +185,17 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_dnsvip", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.222.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.222.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ProvisioningNetworkInterface: "ens3", + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"192.168.222.3\": the virtual IP is expected to be in one of the machine networks", @@ -102,15 +203,17 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_ingressvip", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.222.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.222.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"192.168.222.4\": the virtual IP is expected to be in one of the machine networks", @@ -118,15 +221,17 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_hosts", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: nil, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: nil, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "bare metal hosts are missing", @@ -134,15 +239,17 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_libvirturi", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "invalid URI \"\"", @@ -150,15 +257,17 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_extbridge", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "noexist", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "noexist", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"noexist\": invalid external bridge", @@ -166,48 +275,73 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_provbridge", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "noexist", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "noexist", }, network: network, expected: "Invalid value: \"noexist\": invalid provisioning bridge", }, { - name: "invalid_clusterprovip", + name: "invalid_clusterprovip_machineCIDR", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "192.168.111.5", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "192.168.111.5", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"192.168.111.5\": the IP must not be in one of the machine networks", }, { - name: "invalid_bootstrapprovip", + name: "invalid_clusterprovip_wrongCIDR", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "192.168.128.1", + BootstrapProvisioningIP: "172.22.0.2", + ProvisioningDHCPRange: "172.22.0.10,172.22.0.100", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + }, + network: network, + expected: "Invalid value: \"192.168.128.1\": \"192.168.128.1\" is not in the provisioning network", + }, + { + name: "invalid_bootstrapprovip_machineCIDR", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "192.168.111.5", - ExternalBridge: "br0", - ProvisioningBridge: "br1", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "192.168.111.5", + ExternalBridge: "br0", + ProvisioningBridge: "br1", }, network: network, expected: "Invalid value: \"192.168.111.5\": the IP must not be in one of the machine networks", @@ -215,17 +349,19 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_bootstraposimage", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", }, network: network, expected: "the URI provided.*is invalid", @@ -233,17 +369,19 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_clusterosimage", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http//192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ClusterProvisioningIP: "172.22.0.3", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http//192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", }, network: network, expected: "the URI provided.*is invalid", @@ -251,17 +389,19 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_bootstraposimage_checksum", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?md5sum=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?md5sum=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", }, network: network, expected: "the sha256 parameter in the.*URI is missing", @@ -269,17 +409,19 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_clusterosimage_checksum", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=3ee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "http://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=3ee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", }, network: network, expected: "the sha256 parameter in the.*URI is invalid", @@ -287,21 +429,42 @@ func TestValidatePlatform(t *testing.T) { { name: "invalid_bootstraposimage_uri_scheme", platform: &baremetal.Platform{ - APIVIP: "192.168.111.2", - DNSVIP: "192.168.111.3", - IngressVIP: "192.168.111.4", - Hosts: []*baremetal.Host{}, - LibvirtURI: "qemu://system", - ClusterProvisioningIP: "172.22.0.3", - BootstrapProvisioningIP: "172.22.0.2", - ExternalBridge: "br0", - ProvisioningBridge: "br1", - BootstrapOSImage: "xttp://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", - ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ProvisioningNetworkInterface: "ens3", + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "172.22.0.2", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + BootstrapOSImage: "xttp://192.168.111.1/images/qemu.x86_64.qcow2.gz?sha256=3b5a882c2af3e19d515b961855d144f293cab30190c2bdedd661af31a1fc4e2f", + ClusterOSImage: "http://192.168.111.1/images/metal.x86_64.qcow2.gz?sha256=340dfa4d92450f2eee852ed1e2d02e3138cc68d824827ef9cf0a40a7ea2f93da", }, network: network, expected: "the URI provided.*must begin with http/https", }, + { + name: "invalid_bootstrapprovip_wrongCIDR", + platform: &baremetal.Platform{ + APIVIP: "192.168.111.2", + DNSVIP: "192.168.111.3", + IngressVIP: "192.168.111.4", + Hosts: []*baremetal.Host{}, + LibvirtURI: "qemu://system", + ProvisioningNetworkInterface: "ens3", + ProvisioningNetworkCIDR: ipnet.MustParseCIDR("172.22.0.0/24"), + ClusterProvisioningIP: "172.22.0.3", + BootstrapProvisioningIP: "192.168.128.1", + ProvisioningDHCPRange: "172.22.0.10,172.22.0.100", + ExternalBridge: "br0", + ProvisioningBridge: "br1", + }, + network: network, + expected: "Invalid value: \"192.168.128.1\": \"192.168.128.1\" is not in the provisioning network", + }, } for _, tc := range cases { diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index 3a905fb9da1..f2008697dab 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -92,16 +92,18 @@ func validVSpherePlatform() *vsphere.Platform { func validBareMetalPlatform() *baremetal.Platform { iface, _ := net.Interfaces() return &baremetal.Platform{ - LibvirtURI: "qemu+tcp://192.168.122.1/system", - BootstrapProvisioningIP: "127.0.0.1", - ClusterProvisioningIP: "192.168.111.1", - 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", + LibvirtURI: "qemu+tcp://192.168.122.1/system", + ProvisioningNetworkInterface: "ens3", + 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", } }