Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ AddCapability=NET_ADMIN NET_RAW NET_BIND_SERVICE
Volume=ironic.volume:/shared:z
Environment="PROVISIONING_INTERFACE=${PROVISIONING_INTERFACE}"
Environment="DHCP_RANGE=${DHCP_RANGE}"
Environment="GATEWAY_IP=${GATEWAY_IP}"
Environment="HTTP_PORT=${HTTP_PORT}"

[Service]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ HTTP_PORT=6180
# 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}}"
GATEWAY_IP="{{.PlatformData.BareMetal.ProvisioningNetworkGateway}}"
DHCP_ALLOW_MACS="{{.PlatformData.BareMetal.ProvisioningDHCPAllowList}}"
# Used by ironic to allow ssh to running IPA instances
IRONIC_RAMDISK_SSH_KEY="{{.SSHKey}}"
Expand Down
10 changes: 10 additions & 0 deletions data/data/install.openshift.io_installconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6107,6 +6107,16 @@ spec:
description: ProvisioningNetworkCIDR defines the network to use
for provisioning.
type: string
provisioningNetworkGateway:
description: |-
ProvisioningNetworkGateway is the IP address of the default gateway
for the provisioning network. This gateway is provided to baremetal
hosts via DHCP to enable routing to external networks during
introspection and provisioning. This field is only honored when
provisioningNetwork is set to Managed (installer-managed DHCP).
It is ignored when provisioningNetwork is Unmanaged or Disabled.
format: ip
type: string
provisioningNetworkInterface:
description: |-
ProvisioningNetworkInterface is the name of the network interface on a control plane
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ spec:
provisioningNetworkCIDR: "{{.Baremetal.ProvisioningNetworkCIDR}}"
provisioningNetwork: "{{.Baremetal.ProvisioningNetwork}}"
provisioningDHCPRange: "{{.Baremetal.ProvisioningDHCPRange}}"
provisioningNetworkGateway: "{{.Baremetal.ProvisioningNetworkGateway}}"
provisioningOSDownloadURL: "{{.ProvisioningOSDownloadURL}}"
additionalNTPServers: [{{range $index, $server := .Baremetal.AdditionalNTPServers}}{{if $index}},{{end}}"{{$server}}"{{end}}]
watchAllNamespaces: false
4 changes: 4 additions & 0 deletions pkg/asset/ignition/bootstrap/baremetal/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type TemplateData struct {
// should be blank.
ProvisioningDHCPRange string

// ProvisioningNetworkGateway is the IP address of the default gateway for the provisioning network.
ProvisioningNetworkGateway string

// ProvisioningDHCPAllowList contains a space-separated list of all of the control plane's boot
// MAC addresses. Requests to bootstrap DHCP from other hosts will be ignored.
ProvisioningDHCPAllowList string
Expand Down Expand Up @@ -194,6 +197,7 @@ func GetTemplateData(config *baremetal.Platform, networks []types.MachineNetwork
switch config.ProvisioningNetwork {
case baremetal.ManagedProvisioningNetwork:
cidr, _ := config.ProvisioningNetworkCIDR.Mask.Size()
templateData.ProvisioningNetworkGateway = config.ProvisioningNetworkGateway
// When provisioning network is managed, we set a DHCP range including
// netmask for dnsmasq.
templateData.ProvisioningDHCPRange = fmt.Sprintf("%s,%d", config.ProvisioningDHCPRange, cidr)
Expand Down
11 changes: 11 additions & 0 deletions pkg/types/baremetal/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ type Platform struct {
// +optional
ProvisioningDHCPRange string `json:"provisioningDHCPRange,omitempty"`

// ProvisioningNetworkGateway is the IP address of the default gateway
// for the provisioning network. This gateway is provided to baremetal
// hosts via DHCP to enable routing to external networks during
// introspection and provisioning. This field is only honored when
// provisioningNetwork is set to Managed (installer-managed DHCP).
// It is ignored when provisioningNetwork is Unmanaged or Disabled.
//
// +kubebuilder:validation:Format=ip
// +optional
ProvisioningNetworkGateway string `json:"provisioningNetworkGateway,omitempty"`

// Hosts is the information needed to create the objects in Ironic.
Hosts []*Host `json:"hosts"`

Expand Down
27 changes: 25 additions & 2 deletions pkg/types/baremetal/validation/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ func validateDHCPRange(p *baremetal.Platform, fldPath *field.Path) (allErrs fiel
allErrs = append(allErrs, field.Invalid(fldPath.Child("bootstrapProvisioningIP"), p.BootstrapProvisioningIP, fmt.Sprintf("%q overlaps with the allocated DHCP range", p.BootstrapProvisioningIP)))
}
}
// Validate ProvisioningNetworkGateway is not in DHCP range
if provisioningNetworkGateway := net.ParseIP(p.ProvisioningNetworkGateway); provisioningNetworkGateway != nil && bytes.Compare(provisioningNetworkGateway, start) >= 0 && bytes.Compare(provisioningNetworkGateway, end) <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningNetworkGateway"), p.ProvisioningNetworkGateway, fmt.Sprintf("%q overlaps with the allocated DHCP range", p.ProvisioningNetworkGateway)))
}

return
}
Expand Down Expand Up @@ -461,6 +465,12 @@ func ValidatePlatform(p *baremetal.Platform, agentBasedInstallation bool, n *typ
}
}

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

enabledCaps := c.GetEnabledCapabilities()
if !agentBasedInstallation && enabledCaps.Has(configv1.ClusterVersionCapabilityMachineAPI) && p.Hosts == nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("hosts"), p.Hosts, "bare metal hosts are missing"))
Expand Down Expand Up @@ -602,8 +612,21 @@ func ValidateProvisioningNetworking(p *baremetal.Platform, n *types.Networking,
}

// Ensure clusterProvisioningIP is in the provisioningNetworkCIDR
if !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 p.ClusterProvisioningIP != "" {
if !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)))
}
}

// Ensure provisioningNetworkGateway is in the provisioningNetworkCIDR
if p.ProvisioningNetworkGateway != "" {
if !p.ProvisioningNetworkCIDR.Contains(net.ParseIP(p.ProvisioningNetworkGateway)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningNetworkGateway"), p.ProvisioningNetworkGateway, fmt.Sprintf("%q is not in the provisioning network", p.ProvisioningNetworkGateway)))
}
// Ensure gateway is not the same as clusterProvisioningIP
if p.ProvisioningNetworkGateway == p.ClusterProvisioningIP {
allErrs = append(allErrs, field.Invalid(fldPath.Child("provisioningNetworkGateway"), p.ProvisioningNetworkGateway, "cannot be the same as clusterProvisioningIP"))
}
}

// Ensure provisioningNetworkCIDR does not have any host bits set
Expand Down