Skip to content
Closed
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
25 changes: 21 additions & 4 deletions pkg/asset/manifests/infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package manifests

import (
"fmt"
"net"
"path/filepath"
"strings"

"github.com/ghodss/yaml"
"github.com/pkg/errors"
Expand All @@ -13,6 +15,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

gcpmanifests "github.com/openshift/installer/pkg/asset/manifests/gcp"
"github.com/openshift/installer/pkg/asset/rhcos"
"github.com/openshift/installer/pkg/types/aws"
"github.com/openshift/installer/pkg/types/azure"
"github.com/openshift/installer/pkg/types/baremetal"
Expand Down Expand Up @@ -50,6 +53,7 @@ func (*Infrastructure) Dependencies() []asset.Asset {
&installconfig.InstallConfig{},
&CloudProviderConfig{},
&AdditionalTrustBundleConfig{},
new(rhcos.Image),
}
}

Expand All @@ -59,7 +63,8 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error {
installConfig := &installconfig.InstallConfig{}
cloudproviderconfig := &CloudProviderConfig{}
trustbundleconfig := &AdditionalTrustBundleConfig{}
dependencies.Get(clusterID, installConfig, cloudproviderconfig, trustbundleconfig)
rhcosImage := new(rhcos.Image)
dependencies.Get(clusterID, installConfig, cloudproviderconfig, trustbundleconfig, rhcosImage)

config := &configv1.Infrastructure{
TypeMeta: metav1.TypeMeta{
Expand Down Expand Up @@ -98,10 +103,22 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error {
}
case baremetal.Name:
config.Status.PlatformStatus.Type = configv1.BareMetalPlatformType
// The MAO expects the ProvisioiningDHCPRange in comma-separated format
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The MAO expects the ProvisioiningDHCPRange in comma-separated format
// The MAO expects the ProvisioningDHCPRange in comma-separated format

provDHCPArr := []string{
installConfig.Config.Platform.BareMetal.ProvisioningDHCPStart,
installConfig.Config.Platform.BareMetal.ProvisioningDHCPEnd,
}
provDHCPRange := strings.Join(provDHCPArr, ",")
config.Status.PlatformStatus.BareMetal = &configv1.BareMetalPlatformStatus{
APIServerInternalIP: installConfig.Config.Platform.BareMetal.APIVIP,
NodeDNSIP: installConfig.Config.Platform.BareMetal.DNSVIP,
IngressIP: installConfig.Config.Platform.BareMetal.IngressVIP,
APIServerInternalIP: installConfig.Config.Platform.BareMetal.APIVIP,
NodeDNSIP: installConfig.Config.Platform.BareMetal.DNSVIP,
IngressIP: installConfig.Config.Platform.BareMetal.IngressVIP,
ProvisioningInterface: installConfig.Config.Platform.BareMetal.ProvisioningInterface,
ProvisioningNetworkCIDR: installConfig.Config.Platform.BareMetal.ProvisioningNetworkCIDR,
ProvisioningIP: installConfig.Config.Platform.BareMetal.ClusterProvisioningIP,
ProvisioningDHCPRange: provDHCPRange,
CachedImageURL: installConfig.Config.Platform.BareMetal.CachedImageURL,
RhcosImageURL: string(*rhcosImage),
}
case gcp.Name:
config.Status.PlatformStatus.Type = configv1.GCPPlatformType
Expand Down
58 changes: 52 additions & 6 deletions pkg/types/baremetal/defaults/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,54 @@ import (

"github.com/openshift/installer/pkg/types"
"github.com/openshift/installer/pkg/types/baremetal"

"github.com/apparentlymart/go-cidr/cidr"
)

// 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 = ""
ProvisioningInterface = "ens3"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should there be an interface name default?

ProvisioningNetworkCIDR = "172.22.0.0/24"
CachedImageURL = "http://192.168.111.1/images"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could default this to the .1 address of the ProvisioninghNetworkCIDR I think, then it could work whenever there's an image cache on the provisioning host, not only in the VM libvirt case?

)

// 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 == "" {
p.ProvisioningNetworkCIDR = ProvisioningNetworkCIDR
}

_, provNet, _ := net.ParseCIDR(p.ProvisioningNetworkCIDR)

if p.BootstrapProvisioningIP == "" {
p.BootstrapProvisioningIP = BootstrapProvisioningIP
// Default to .2 address for CIDR e.g 172.22.0.2
ip, err := cidr.Host(provNet, 2)
if err == nil {
p.BootstrapProvisioningIP = ip.String()
}
}

if p.ClusterProvisioningIP == "" {
p.ClusterProvisioningIP = ClusterProvisioningIP
// Default to .3 address for CIDR e.g 172.22.0.3
ip, err := cidr.Host(provNet, 3)
if err == nil {
p.ClusterProvisioningIP = ip.String()
}
}

if p.ExternalBridge == "" {
Expand All @@ -50,7 +72,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())
Expand All @@ -61,12 +83,36 @@ 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())
} else {
p.IngressVIP = vip[0]
}
}

if p.ProvisioningInterface == "" {
p.ProvisioningInterface = ProvisioningInterface
}

if p.ProvisioningDHCPStart == "" {
// Default to .20 address for CIDR e.g 172.22.0.20
ip, err := cidr.Host(provNet, 20)
if err == nil {
p.ProvisioningDHCPStart = ip.String()
}
}

if p.ProvisioningDHCPEnd == "" {
// Default to .200 address for CIDR e.g 172.22.0.200
ip, err := cidr.Host(provNet, 200)
if err == nil {
p.ProvisioningDHCPEnd = ip.String()
}
}

if p.CachedImageURL == "" {
p.CachedImageURL = CachedImageURL
}
}
85 changes: 85 additions & 0 deletions pkg/types/baremetal/defaults/platform_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package defaults

import (
"errors"
"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",
ProvisioningInterface: "ens3",
ProvisioningNetworkCIDR: "172.22.0.0/24",
ProvisioningDHCPStart: "172.22.0.20",
ProvisioningDHCPEnd: "172.22.0.200",
CachedImageURL: "http://192.168.111.1/images",
},
},
{
name: "alternate_cidr",
platform: &baremetal.Platform{
ProvisioningNetworkCIDR: "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",
ProvisioningInterface: "ens3",
ProvisioningNetworkCIDR: "172.23.0.0/24",
ProvisioningDHCPStart: "172.23.0.20",
ProvisioningDHCPEnd: "172.23.0.200",
CachedImageURL: "http://192.168.111.1/images",
},
},
}
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")
})
}
}
25 changes: 25 additions & 0 deletions pkg/types/baremetal/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ type Platform struct {
// ClusterProvisioningIP is the IP on the dedicated provisioning network
// where the baremetal-operator pod runs provisioning services,
// and an http server to cache some downloaded content e.g RHCOS/IPA images
// Defaults to the .3 address of ProvisioningNetworkCIDR
// +optional
ClusterProvisioningIP string `json:"provisioningHostIP,omitempty"`

// BootstrapProvisioningIP is the IP used on the bootstrap VM to
// bring up provisioning services that are used to create the
// control-plane machines
// Defaults to the .2 address of ProvisioningNetworkCIDR
// +optional
BootstrapProvisioningIP string `json:"bootstrapProvisioningIP,omitempty"`

Expand Down Expand Up @@ -61,4 +63,27 @@ type Platform struct {

// DNSVIP is the VIP to use for internal DNS communication
DNSVIP string `json:"dnsVIP"`

// ProvisioningInterface is the network interface used to provision new hosts.
// +optional
ProvisioningInterface string `json:"provisioningInterface"`

// ProvisioningNetworkCIDR defines the network to use for provisioning.
// +optional
ProvisioningNetworkCIDR string `json:"provisioningNetworkCIDR"`

// ProvisioningDHCPStart is the start of the DHCP range to use to assign hosts during provisioning.
// Defaults to the .20 address of ProvisioningNetworkCIDR
// +optional
ProvisioningDHCPStart string `json:"provisioningDHCPStart"`

// ProvisioningDHCPEnd is the end of the DHCP range to use to assign hosts during provisioning.
// Defaults to the .200 address of ProvisioningNetworkCIDR
// +optional
ProvisioningDHCPEnd string `json:"provisioningDHCPEnd"`

// An HTTP server URL which contains a cached image of the RHCOS image to deploy.
// Defaults to http://192.168.111.1/images for VM based testing
// +optional
CachedImageURL string `json:"cachedImageURL"`
}
39 changes: 39 additions & 0 deletions pkg/types/baremetal/validation/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,44 @@ func ValidatePlatform(p *baremetal.Platform, n *types.Networking, fldPath *field
allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapHostIP"), p.BootstrapProvisioningIP, err.Error()))
}

// Make sure the provisioning interface is set. Very little we can do to validate this
// as it's not on this machine.
if p.ProvisioningInterface == "" {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningInterface"), p.ProvisioningInterface, "Baremetal provisioning interface unset."))
}

_, provNetwork, err := net.ParseCIDR(p.ProvisioningNetworkCIDR)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningNetworkCIDR"), p.ProvisioningNetworkCIDR, err.Error()))
}

if provNetwork.Contains(net.ParseIP(p.ClusterProvisioningIP)) != true {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningHostIP"), p.ClusterProvisioningIP, "IP not in provisioning network."))
}

if provNetwork.Contains(net.ParseIP(p.BootstrapProvisioningIP)) != true {
allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapHostIP"), p.BootstrapProvisioningIP, "IP not in provisioning network."))
}

if err := validate.IP(p.ProvisioningDHCPStart); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPStart"), p.ProvisioningDHCPStart, err.Error()))
}

if provNetwork.Contains(net.ParseIP(p.ProvisioningDHCPStart)) != true {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPStart"), p.ProvisioningDHCPStart, "IP not in provisioning network."))
}

if err := validate.IP(p.ProvisioningDHCPEnd); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPEnd"), p.ProvisioningDHCPEnd, err.Error()))
}

if provNetwork.Contains(net.ParseIP(p.ProvisioningDHCPEnd)) != true {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningDHCPEnd"), p.ProvisioningDHCPEnd, "IP not in provisioning network."))
}

if err := validate.URI(p.CachedImageURL); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("cachedImageURL"), p.CachedImageURL, err.Error()))
}

return allErrs
}
Loading