Skip to content

Commit

Permalink
Add OpenStack provider (#540)
Browse files Browse the repository at this point in the history
* add openstack provider

* fmt

* add flags

* address review

* wire templates

* fix podscidr

* add more flags

* fmt

* remove control plane machine flavor for now

* fix newline

* add node cidr

* fix node cidr

* hide openstack flags, drop ssh key support

* Fix path

* Remove false commit

Co-authored-by: Marcel Mueller <marcel.mueller1@rwth-aachen.de>
  • Loading branch information
tfussell and MarcelMue committed Dec 6, 2021
1 parent a195856 commit cb70e66
Show file tree
Hide file tree
Showing 21 changed files with 483 additions and 81 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project's packages adheres to [Semantic Versioning](http://semver.org/s

## [Unreleased]

### Added

- Add alpha support for OpenStack cluster templating.

## [1.54.0] - 2021-12-03

### Fixed
Expand Down
61 changes: 44 additions & 17 deletions cmd/get/capi/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import (
const (
giantswarmNamespace = "giantswarm"

providerAll = "All"
providerAWS = "AWS"
providerAzure = "Azure"
providerVMware = "VMware"
providerAll = "All"
providerAWS = "AWS"
providerAzure = "Azure"
providerOpenStack = "OpenStack"
providerVSphere = "vSphere"
)

type runner struct {
Expand All @@ -47,6 +48,7 @@ type controller struct {

var (
crds = []crd{
// All
{
DisplayName: "Cluster",
Name: "clusters.cluster.x-k8s.io",
Expand Down Expand Up @@ -102,6 +104,7 @@ var (
Name: "kubeadmconfigtemplates.bootstrap.cluster.x-k8s.io",
Provider: providerAll,
},
// AWS
{
DisplayName: "AWS Cluster",
Name: "awsclusters.infrastructure.cluster.x-k8s.io",
Expand All @@ -122,6 +125,7 @@ var (
Name: "awsmachinetemplates.infrastructure.cluster.x-k8s.io",
Provider: providerAWS,
},
// Azure
{
DisplayName: "Azure Cluster",
Name: "azureclusters.infrastructure.cluster.x-k8s.io",
Expand All @@ -142,30 +146,47 @@ var (
Name: "azuremachinetemplates.infrastructure.cluster.x-k8s.io",
Provider: providerAzure,
},
// Open Stack
{
DisplayName: "VMware Cluster",
DisplayName: "OpenStack Cluster",
Name: "openstackclusters.infrastructure.cluster.x-k8s.io",
Provider: providerOpenStack,
},
{
DisplayName: "OpenStack Machine",
Name: "openstackmachines.infrastructure.cluster.x-k8s.io",
Provider: providerOpenStack,
},
{
DisplayName: "OpenStack Machine Template",
Name: "openstackmachinetemplates.infrastructure.cluster.x-k8s.io",
Provider: providerOpenStack,
},
// vSphere
{
DisplayName: "vSphere Cluster",
Name: "vsphereclusters.infrastructure.cluster.x-k8s.io",
Provider: providerVMware,
Provider: providerVSphere,
},
{
DisplayName: "VMware Machine",
DisplayName: "vSphere Machine",
Name: "vspheremachines.infrastructure.cluster.x-k8s.io",
Provider: providerVMware,
Provider: providerVSphere,
},
{
DisplayName: "VMware Machine Template",
DisplayName: "vSphere Machine Template",
Name: "vspheremachinetemplates.infrastructure.cluster.x-k8s.io",
Provider: providerVMware,
Provider: providerVSphere,
},
{
DisplayName: "VMware VM",
DisplayName: "vSphere VM",
Name: "vspherevms.infrastructure.cluster.x-k8s.io",
Provider: providerVMware,
Provider: providerVSphere,
},
{
DisplayName: "VMware HAProxy",
DisplayName: "vSphere HAProxy",
Name: "haproxyloadbalancers.infrastructure.cluster.x-k8s.io",
Provider: providerVMware,
Provider: providerVSphere,
},
}

Expand Down Expand Up @@ -201,10 +222,16 @@ var (
Provider: providerAzure,
},
{
DisplayName: "VMWare Provider",
LabelSelector: "app.kubernetes.io/name=cluster-api-provider-vmware",
DisplayName: "OpenStack Provider",
LabelSelector: "app.kubernetes.io/name=cluster-api-provider-openstack",
ContainerName: "manager",
Provider: providerOpenStack,
},
{
DisplayName: "vSphere Provider",
LabelSelector: "app.kubernetes.io/name=cluster-api-provider-vsphere",
ContainerName: "manager",
Provider: providerVMware,
Provider: providerVSphere,
},
}
)
Expand Down
100 changes: 82 additions & 18 deletions cmd/template/cluster/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ const (
flagProvider = "provider"

// AWS only.
flagExternalSNAT = "external-snat"
flagEKS = "aws-eks"
flagPodsCIDR = "pods-cidr"
flagControlPlaneSubnet = "control-plane-subnet"
flagAWSExternalSNAT = "external-snat"
flagAWSEKS = "aws-eks"
flagAWSControlPlaneSubnet = "control-plane-subnet"

// OpenStack only.
flagOpenStackCloud = "cloud"
flagOpenStackCloudConfig = "cloud-config"
flagOpenStackDNSNameservers = "dns-nameservers"
flagOpenStackExternalNetworkID = "external-network-id"
flagOpenStackFailureDomain = "failure-domain"
flagOpenStackImageName = "image-name"
flagOpenStackNodeMachineFlavor = "node-machine-flavor"
flagOpenStackNodeCIDR = "node-cidr"
flagOpenStackRootVolumeDiskSize = "root-volume-disk-size"
flagOpenStackRootVolumeSourceType = "root-volume-source-type"
flagOpenStackRootVolumeSourceUUID = "root-volume-source-uuid"

// Common.
flagClusterIDDeprecated = "cluster-id"
Expand All @@ -31,18 +43,36 @@ const (
flagOutput = "output"
flagOrganization = "organization"
flagOwner = "owner" // TODO: Remove some time after December 2021
flagPodsCIDR = "pods-cidr"
flagRelease = "release"
flagLabel = "label"
)

type flag struct {
Provider string

// AWS only.
type awsFlag struct {
ControlPlaneSubnet string
ExternalSNAT bool
EKS bool
PodsCIDR string
}

type openStackFlag struct {
Cloud string // OPENSTACK_CLOUD
CloudConfig string // <no equivalent env var>
DNSNameservers []string // OPENSTACK_DNS_NAMESERVERS
ExternalNetworkID string // <no equivalent env var>
FailureDomain string // OPENSTACK_FAILURE_DOMAIN
ImageName string // OPENSTACK_IMAGE_NAME
NodeMachineFlavor string // OPENSTACK_NODE_MACHINE_FLAVOR
RootVolumeDiskSize string // <no equivalent env var>
RootVolumeSourceType string // <no equivalent env var>
RootVolumeSourceUUID string // <no equivalent env var>
NodeCIDR string // <no equivalent env var>
}

type flag struct {
Provider string

AWS awsFlag
OpenStack openStackFlag

// Common.
ClusterIDDeprecated string
Expand All @@ -53,6 +83,7 @@ type flag struct {
Output string
Organization string
Owner string
PodsCIDR string
Release string
Label []string

Expand All @@ -64,10 +95,35 @@ func (f *flag) Init(cmd *cobra.Command) {
cmd.Flags().StringVar(&f.Provider, flagProvider, "", "Installation infrastructure provider.")

// AWS only.
cmd.Flags().StringVar(&f.ControlPlaneSubnet, flagControlPlaneSubnet, "", "Subnet used for the Control Plane.")
cmd.Flags().BoolVar(&f.ExternalSNAT, flagExternalSNAT, false, "AWS CNI configuration.")
cmd.Flags().BoolVar(&f.EKS, flagEKS, false, "Enable EKS. Only available for AWS Release v20.0.0 (CAPA)")
cmd.Flags().StringVar(&f.PodsCIDR, flagPodsCIDR, "", "CIDR used for the pods.")
cmd.Flags().StringVar(&f.AWS.ControlPlaneSubnet, flagAWSControlPlaneSubnet, "", "Subnet used for the Control Plane.")
cmd.Flags().BoolVar(&f.AWS.ExternalSNAT, flagAWSExternalSNAT, false, "AWS CNI configuration.")
cmd.Flags().BoolVar(&f.AWS.EKS, flagAWSEKS, false, "Enable AWSEKS. Only available for AWS Release v20.0.0 (CAPA)")

// OpenStack only.
cmd.Flags().StringVar(&f.OpenStack.Cloud, flagOpenStackCloud, "openstack", "Name of cloud (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.CloudConfig, flagOpenStackCloudConfig, "cloud-config", "Name of cloud config (OpenStack only).")
cmd.Flags().StringSliceVar(&f.OpenStack.DNSNameservers, flagOpenStackDNSNameservers, nil, "DNS nameservers (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.ExternalNetworkID, flagOpenStackExternalNetworkID, "", "External network ID (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.FailureDomain, flagOpenStackFailureDomain, "", "Failure domain (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.ImageName, flagOpenStackImageName, "ubuntu-2004-kube-v1.20.9", "Image name (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.NodeMachineFlavor, flagOpenStackNodeMachineFlavor, "", "Node machine flavor (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.RootVolumeDiskSize, flagOpenStackRootVolumeDiskSize, "", "Root volume disk size (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.RootVolumeSourceType, flagOpenStackRootVolumeSourceType, "", "Root volume source type (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.RootVolumeSourceUUID, flagOpenStackRootVolumeSourceUUID, "", "Root volume source UUID (OpenStack only).")
cmd.Flags().StringVar(&f.OpenStack.NodeCIDR, flagOpenStackNodeCIDR, "", "CIDR used for the nodes.")

// TODO: Make these flags visible once we have a better method for displaying provider-specific flags.
_ = cmd.Flags().MarkHidden(flagOpenStackCloud)
_ = cmd.Flags().MarkHidden(flagOpenStackCloudConfig)
_ = cmd.Flags().MarkHidden(flagOpenStackDNSNameservers)
_ = cmd.Flags().MarkHidden(flagOpenStackExternalNetworkID)
_ = cmd.Flags().MarkHidden(flagOpenStackFailureDomain)
_ = cmd.Flags().MarkHidden(flagOpenStackImageName)
_ = cmd.Flags().MarkHidden(flagOpenStackNodeMachineFlavor)
_ = cmd.Flags().MarkHidden(flagOpenStackRootVolumeDiskSize)
_ = cmd.Flags().MarkHidden(flagOpenStackRootVolumeSourceType)
_ = cmd.Flags().MarkHidden(flagOpenStackRootVolumeSourceUUID)
_ = cmd.Flags().MarkHidden(flagOpenStackNodeCIDR)

// Common.
cmd.Flags().StringVar(&f.ClusterIDDeprecated, flagClusterIDDeprecated, "", "Unique identifier of the cluster (deprecated).")
Expand All @@ -78,11 +134,12 @@ func (f *flag) Init(cmd *cobra.Command) {
cmd.Flags().StringVar(&f.Output, flagOutput, "", "File path for storing CRs.")
cmd.Flags().StringVar(&f.Organization, flagOrganization, "", "Workload cluster organization.")
cmd.Flags().StringVar(&f.Owner, flagOwner, "", "Workload cluster owner organization (deprecated).")
cmd.Flags().StringVar(&f.PodsCIDR, flagPodsCIDR, "", "CIDR used for the pods.")
cmd.Flags().StringVar(&f.Release, flagRelease, "", "Workload cluster release.")
cmd.Flags().StringSliceVar(&f.Label, flagLabel, nil, "Workload cluster label.")

// TODO: Make this flag visible when we roll CAPA/EKS out for customers
_ = cmd.Flags().MarkHidden(flagEKS)
_ = cmd.Flags().MarkHidden(flagAWSEKS)

// TODO: Remove the flag completely some time after August 2021
_ = cmd.Flags().MarkDeprecated(flagMasterAZ, "please use --control-plane-az.")
Expand Down Expand Up @@ -124,7 +181,8 @@ func (f *flag) Validate() error {
validProviders := []string{
key.ProviderAWS,
key.ProviderAzure,
key.ProviderVsphere,
key.ProviderOpenStack,
key.ProviderVSphere,
}
isValidProvider := false
for _, p := range validProviders {
Expand Down Expand Up @@ -159,10 +217,10 @@ func (f *flag) Validate() error {
return microerror.Maskf(invalidFlagError, "--%s must only contain alphanumeric characters, and start with a letter", flagName)
}

if f.ControlPlaneSubnet != "" {
matchedSubnet, err := regexp.MatchString("^20|21|22|23|24|25$", f.ControlPlaneSubnet)
if f.AWS.ControlPlaneSubnet != "" {
matchedSubnet, err := regexp.MatchString("^20|21|22|23|24|25$", f.AWS.ControlPlaneSubnet)
if err == nil && !matchedSubnet {
return microerror.Maskf(invalidFlagError, "--%s must be a valid subnet size (20, 21, 22, 23, 24 or 25)", flagControlPlaneSubnet)
return microerror.Maskf(invalidFlagError, "--%s must be a valid subnet size (20, 21, 22, 23, 24 or 25)", flagAWSControlPlaneSubnet)
}
}
}
Expand Down Expand Up @@ -198,6 +256,12 @@ func (f *flag) Validate() error {
if len(f.ControlPlaneAZ) > 1 {
return microerror.Maskf(invalidFlagError, "--%s supports one availability zone only", flagControlPlaneAZ)
}
case key.ProviderOpenStack:
if f.OpenStack.NodeCIDR != "" {
if !validateCIDR(f.OpenStack.NodeCIDR) {
return microerror.Maskf(invalidFlagError, "--%s must be a valid CIDR", flagOpenStackNodeCIDR)
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions cmd/template/cluster/provider/capa.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func WriteCAPATemplate(ctx context.Context, client k8sclient.Interface, out io.W
Name string
Namespace string
Organization string
PodsCIDR string
ReleaseVersion string
SSHDConfig string
SSOPublicKey string
Expand All @@ -39,6 +40,7 @@ func WriteCAPATemplate(ctx context.Context, client k8sclient.Interface, out io.W
Name: config.Name,
Namespace: key.OrganizationNamespaceFromName(config.Organization),
Organization: config.Organization,
PodsCIDR: config.PodsCIDR,
ReleaseVersion: config.ReleaseVersion,
SSHDConfig: key.NodeSSHDConfigEncoded(),
SSOPublicKey: sshSSOPublicKey,
Expand Down
67 changes: 67 additions & 0 deletions cmd/template/cluster/provider/capo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package provider

import (
"context"
"io"

"github.com/giantswarm/k8sclient/v5/pkg/k8sclient"
"github.com/giantswarm/microerror"

"github.com/giantswarm/kubectl-gs/cmd/template/cluster/provider/templates/openstack"
)

func WriteOpenStackTemplate(ctx context.Context, client k8sclient.Interface, out io.Writer, config ClusterCRsConfig) error {
data := struct {
Description string
KubernetesVersion string
Name string
Namespace string
Organization string
PodsCIDR string
ReleaseVersion string

Cloud string // OPENSTACK_CLOUD
CloudConfig string // <no equivalent env var>
DNSNameservers []string // OPENSTACK_DNS_NAMESERVERS
ExternalNetworkID string // <no equivalent env var>
FailureDomain string // OPENSTACK_FAILURE_DOMAIN
ImageName string // OPENSTACK_IMAGE_NAME
NodeCIDR string // <no equivalent env var>
NodeMachineFlavor string // OPENSTACK_NODE_MACHINE_FLAVOR
RootVolumeDiskSize string // <no equivalent env var>
RootVolumeSourceType string // <no equivalent env var>
RootVolumeSourceUUID string // <no equivalent env var>
}{
Description: config.Description,
KubernetesVersion: "v1.20.9",
Name: config.Name,
Namespace: config.Namespace,
Organization: config.Organization,
PodsCIDR: config.PodsCIDR,
ReleaseVersion: config.ReleaseVersion,

Cloud: config.Cloud,
CloudConfig: config.CloudConfig,
DNSNameservers: config.DNSNameservers,
ExternalNetworkID: config.ExternalNetworkID,
FailureDomain: config.FailureDomain,
ImageName: config.ImageName,
NodeCIDR: config.NodeCIDR,
NodeMachineFlavor: config.NodeMachineFlavor,
RootVolumeDiskSize: config.RootVolumeDiskSize,
RootVolumeSourceType: config.RootVolumeSourceType,
RootVolumeSourceUUID: config.RootVolumeSourceUUID,
}

var templates []templateConfig
for _, t := range openstack.GetTemplates() {
templates = append(templates, templateConfig(t))
}

err := runMutation(ctx, client, data, templates, out)
if err != nil {
return microerror.Mask(err)
}

return nil
}

0 comments on commit cb70e66

Please sign in to comment.