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
2 changes: 2 additions & 0 deletions data/data/openstack/bootstrap/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ resource "openstack_networking_port_v2" "bootstrap_port" {
allowed_address_pairs {
ip_address = var.node_dns_ip
}

depends_on = [var.master_port_ids]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is to make sure that the bootstrap port is created after the master ports, which in turn are created after the api and ingress.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

would like to see this part of the commit message ❤️

}

data "openstack_compute_flavor_v2" "bootstrap_flavor" {
Expand Down
4 changes: 4 additions & 0 deletions data/data/openstack/bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,7 @@ variable "nodes_subnet_id" {
variable "cluster_domain" {
type = string
}

variable "master_port_ids" {
type = list(string)
}
1 change: 1 addition & 0 deletions data/data/openstack/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module "bootstrap" {
private_network_id = module.topology.private_network_id
master_sg_id = module.topology.master_sg_id
bootstrap_shim_ignition = var.openstack_bootstrap_shim_ignition
master_port_ids = module.topology.master_port_ids
}

module "masters" {
Expand Down
8 changes: 4 additions & 4 deletions data/data/openstack/topology/private-network.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ resource "openstack_networking_port_v2" "masters" {
allowed_address_pairs {
ip_address = var.ingress_ip
}

depends_on = [openstack_networking_port_v2.api_port, openstack_networking_port_v2.ingress_port]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since masters get random ips, we must add this dependency so that master are created after api and ingress ports.

}

resource "openstack_networking_port_v2" "api_port" {
Expand All @@ -73,8 +75,7 @@ resource "openstack_networking_port_v2" "api_port" {
tags = ["openshiftClusterID=${var.cluster_id}"]

fixed_ip {
subnet_id = openstack_networking_subnet_v2.nodes.id
# FIXME(mandre) we could let the installer automatically pick up the address
subnet_id = openstack_networking_subnet_v2.nodes.id
ip_address = var.api_int_ip
}
}
Expand All @@ -88,8 +89,7 @@ resource "openstack_networking_port_v2" "ingress_port" {
tags = ["openshiftClusterID=${var.cluster_id}"]

fixed_ip {
subnet_id = openstack_networking_subnet_v2.nodes.id
# FIXME(mandre) we could let the installer automatically pick up the address
subnet_id = openstack_networking_subnet_v2.nodes.id
ip_address = var.ingress_ip
}
}
Expand Down
4 changes: 3 additions & 1 deletion docs/user/openstack/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ Beyond the [platform-agnostic `install-config.yaml` properties](../customization
* `octaviaSupport` (optional string): Whether OpenStack supports Octavia (`1` for true or `0` for false)
* `region` (deprecated string): The OpenStack region where the cluster will be created. Currently this value is not used by the installer.
* `trunkSupport` (optional string): Whether OpenStack ports can be trunked (`1` for true or `0` for false)
* `clusterOSImage` (optional string): Either a URL with `http(s)` or `file` scheme to override the default OS image for cluster nodes or an existing Glance image name.
* `clusterOSimage` (optional string): Either a URL with `http(s)` or `file` scheme to override the default OS image for cluster nodes or an existing Glance image name.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This needs to match the Go JSON serialization. Fixed via #3439.

* `apiVIP` (optional string): An IP addresss on the machineNetwork that will be assigned to the API VIP. Be aware that the `10` and `11` of the machineNetwork will be taken by neutron dhcp by default, and wont be available.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

any link to documentation that provides the 10, 11 being reserved?

* `ingressVIP` (optional string): An IP address on the machineNetwork that will be assigned to the ingress VIP. Be aware that the `10` and `11` of the machineNetwork will be taken by neutron dhcp by default, and wont be available.

## Machine pools

Expand Down
12 changes: 2 additions & 10 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,27 +363,19 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
if err != nil {
return err
}
apiVIP, err := openstackdefaults.APIVIP(installConfig.Config.Networking)
if err != nil {
return err
}
dnsVIP, err := openstackdefaults.DNSVIP(installConfig.Config.Networking)
if err != nil {
return err
}
ingressVIP, err := openstackdefaults.IngressVIP(installConfig.Config.Networking)
if err != nil {
return err
}
data, err = openstacktfvars.TFVars(
masters[0].Spec.ProviderSpec.Value.Object.(*openstackprovider.OpenstackProviderSpec),
installConfig.Config.Platform.OpenStack.Cloud,
installConfig.Config.Platform.OpenStack.ExternalNetwork,
installConfig.Config.Platform.OpenStack.ExternalDNS,
installConfig.Config.Platform.OpenStack.LbFloatingIP,
apiVIP.String(),
installConfig.Config.Platform.OpenStack.APIVIP,
dnsVIP.String(),
ingressVIP.String(),
installConfig.Config.Platform.OpenStack.IngressVIP,
installConfig.Config.Platform.OpenStack.TrunkSupport,
installConfig.Config.Platform.OpenStack.OctaviaSupport,
string(*rhcosImage),
Expand Down
6 changes: 1 addition & 5 deletions pkg/asset/ignition/machine/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/openshift/installer/pkg/types"
baremetaltypes "github.com/openshift/installer/pkg/types/baremetal"
openstacktypes "github.com/openshift/installer/pkg/types/openstack"
openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
ovirttypes "github.com/openshift/installer/pkg/types/ovirt"
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
)
Expand All @@ -29,10 +28,7 @@ func pointerIgnitionConfig(installConfig *types.InstallConfig, rootCA []byte, ro
// way to configure DNS before Ignition runs.
ignitionHost = net.JoinHostPort(installConfig.BareMetal.APIVIP, "22623")
case openstacktypes.Name:
apiVIP, err := openstackdefaults.APIVIP(installConfig.Networking)
if err == nil {
ignitionHost = net.JoinHostPort(apiVIP.String(), "22623")
}
ignitionHost = net.JoinHostPort(installConfig.OpenStack.APIVIP, "22623")
case ovirttypes.Name:
ignitionHost = net.JoinHostPort(installConfig.Ovirt.APIVIP, "22623")
case vspheretypes.Name:
Expand Down
12 changes: 2 additions & 10 deletions pkg/asset/manifests/infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,14 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error {
config.Status.PlatformStatus.Type = configv1.NonePlatformType
case openstack.Name:
config.Status.PlatformStatus.Type = configv1.OpenStackPlatformType
apiVIP, err := openstackdefaults.APIVIP(installConfig.Config.Networking)
if err != nil {
return err
}
dnsVIP, err := openstackdefaults.DNSVIP(installConfig.Config.Networking)
if err != nil {
return err
}
ingressVIP, err := openstackdefaults.IngressVIP(installConfig.Config.Networking)
if err != nil {
return err
}
config.Status.PlatformStatus.OpenStack = &configv1.OpenStackPlatformStatus{
APIServerInternalIP: apiVIP.String(),
APIServerInternalIP: installConfig.Config.OpenStack.APIVIP,
NodeDNSIP: dnsVIP.String(),
IngressIP: ingressVIP.String(),
IngressIP: installConfig.Config.OpenStack.IngressVIP,
}
case vsphere.Name:
config.Status.PlatformStatus.Type = configv1.VSpherePlatformType
Expand Down
9 changes: 2 additions & 7 deletions pkg/asset/tls/mcscertkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/openshift/installer/pkg/asset/installconfig"
baremetaltypes "github.com/openshift/installer/pkg/types/baremetal"
openstacktypes "github.com/openshift/installer/pkg/types/openstack"
openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
ovirttypes "github.com/openshift/installer/pkg/types/ovirt"
vspheretypes "github.com/openshift/installer/pkg/types/vsphere"
)
Expand Down Expand Up @@ -50,12 +49,8 @@ func (a *MCSCertKey) Generate(dependencies asset.Parents) error {
cfg.IPAddresses = []net.IP{net.ParseIP(installConfig.Config.BareMetal.APIVIP)}
cfg.DNSNames = []string{hostname, installConfig.Config.BareMetal.APIVIP}
case openstacktypes.Name:
apiVIP, err := openstackdefaults.APIVIP(installConfig.Config.Networking)
if err != nil {
return err
}
cfg.IPAddresses = []net.IP{apiVIP}
cfg.DNSNames = []string{hostname, apiVIP.String()}
cfg.IPAddresses = []net.IP{net.ParseIP(installConfig.Config.OpenStack.APIVIP)}
cfg.DNSNames = []string{hostname, installConfig.Config.OpenStack.APIVIP}
case ovirttypes.Name:
cfg.IPAddresses = []net.IP{net.ParseIP(installConfig.Config.Ovirt.APIVIP)}
cfg.DNSNames = []string{hostname, installConfig.Config.Ovirt.APIVIP}
Expand Down
2 changes: 1 addition & 1 deletion pkg/types/defaults/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func SetInstallConfigDefaults(c *types.InstallConfig) {
case c.Platform.Libvirt != nil:
libvirtdefaults.SetPlatformDefaults(c.Platform.Libvirt)
case c.Platform.OpenStack != nil:
openstackdefaults.SetPlatformDefaults(c.Platform.OpenStack)
openstackdefaults.SetPlatformDefaults(c.Platform.OpenStack, c.Networking)
case c.Platform.VSphere != nil:
vspheredefaults.SetPlatformDefaults(c.Platform.VSphere, c)
case c.Platform.BareMetal != nil:
Expand Down
2 changes: 1 addition & 1 deletion pkg/types/defaults/installconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func defaultLibvirtInstallConfig() *types.InstallConfig {
func defaultOpenStackInstallConfig() *types.InstallConfig {
c := defaultInstallConfig()
c.Platform.OpenStack = &openstack.Platform{}
openstackdefaults.SetPlatformDefaults(c.Platform.OpenStack)
openstackdefaults.SetPlatformDefaults(c.Platform.OpenStack, c.Networking)
return c
}

Expand Down
35 changes: 18 additions & 17 deletions pkg/types/openstack/defaults/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,31 @@ const (
)

// SetPlatformDefaults sets the defaults for the platform.
func SetPlatformDefaults(p *openstack.Platform) {
func SetPlatformDefaults(p *openstack.Platform, n *types.Networking) {
if p.Cloud == "" {
p.Cloud = os.Getenv("OS_CLOUD")
if p.Cloud == "" {
p.Cloud = DefaultCloudName
}
}
}
// APIVIP returns the internal virtual IP address (VIP) put in front
// of the Kubernetes API server for use by components inside the
// cluster. The DNS static pods running on the nodes resolve the
// api-int record to APIVIP.
if p.APIVIP == "" {
vip, _ := cidr.Host(&n.MachineNetwork[0].CIDR.IPNet, 5)
p.APIVIP = vip.String()
}

// APIVIP returns the internal virtual IP address (VIP) put in front
// of the Kubernetes API server for use by components inside the
// cluster. The DNS static pods running on the nodes resolve the
// api-int record to APIVIP.
func APIVIP(networking *types.Networking) (net.IP, error) {
return cidr.Host(&networking.MachineNetwork[0].CIDR.IPNet, 5)
// IngressVIP returns the internal virtual IP address (VIP) put in
// front of the OpenShift router pods. This provides the internal
// accessibility to the internal pods running on the worker nodes,
// e.g. `console`. The DNS static pods running on the nodes resolve
// the wildcard apps record to IngressVIP.
if p.IngressVIP == "" {
vip, _ := cidr.Host(&n.MachineNetwork[0].CIDR.IPNet, 7)
p.IngressVIP = vip.String()
}
}

// DNSVIP returns the internal virtual IP address (VIP) put in front
Expand All @@ -40,12 +50,3 @@ func APIVIP(networking *types.Networking) (net.IP, error) {
func DNSVIP(networking *types.Networking) (net.IP, error) {
return cidr.Host(&networking.MachineNetwork[0].CIDR.IPNet, 6)
}

// IngressVIP returns the internal virtual IP address (VIP) put in
// front of the OpenShift router pods. This provides the internal
// accessibility to the internal pods running on the worker nodes,
// e.g. `console`. The DNS static pods running on the nodes resolve
// the wildcard apps record to IngressVIP.
func IngressVIP(networking *types.Networking) (net.IP, error) {
return cidr.Host(&networking.MachineNetwork[0].CIDR.IPNet, 7)
}
10 changes: 10 additions & 0 deletions pkg/types/openstack/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,14 @@ type Platform struct {
// the default OS image for cluster nodes, or an existing Glance image name.
// +optional
ClusterOSImage string `json:"clusterOSImage,omitempty"`

// APIVIP is the static IP on the nodes subnet that the api port for openshift will be assigned
// Default: will be set to the 5 on the first entry in the machineNetwork CIDR
// +optional
APIVIP string `json:"apiVIP,omitempty"`

// IngressVIP is the static IP on the nodes subnet that the apps port for openshift will be assigned
// Default: will be set to the 7 on the first entry in the machineNewtwork CIDR
// +optional
IngressVIP string `json:"ingressVIP,omitempty"`
}
26 changes: 25 additions & 1 deletion pkg/types/openstack/validation/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package validation

import (
"errors"
"net"

"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/validation/field"
Expand Down Expand Up @@ -61,10 +62,20 @@ func ValidatePlatform(p *openstack.Platform, n *types.Networking, fldPath *field

for _, ip := range p.ExternalDNS {
if err := validate.IP(ip); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("ExternalDNS"), p.ExternalDNS, err.Error()))
allErrs = append(allErrs, field.Invalid(fldPath.Child("externalDNS"), p.ExternalDNS, err.Error()))
}
}

err = validateVIP(p.APIVIP, n)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("apiVIP"), p.APIVIP, err.Error()))
}

err = validateVIP(p.IngressVIP, n)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("ingressVIP"), p.IngressVIP, err.Error()))
}

return allErrs
}

Expand All @@ -76,3 +87,16 @@ func isValidValue(s string, validValues []string) bool {
}
return false
}

func validateVIP(vip string, n *types.Networking) error {
if vip != "" {
if err := validate.IP(vip); err != nil {
return err
}

if !n.MachineNetwork[0].CIDR.Contains(net.ParseIP(vip)) {
return errors.New("IP is not in the machineNetwork")
}
}
return nil
}
Loading