Skip to content

Commit

Permalink
Add DHCP server create configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
Karthik-K-N committed Feb 28, 2024
1 parent 40efa1d commit d78c229
Show file tree
Hide file tree
Showing 26 changed files with 1,011 additions and 639 deletions.
4 changes: 3 additions & 1 deletion api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 92 additions & 10 deletions api/v1beta2/ibmpowervscluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ type IBMPowerVSClusterSpec struct {
ServiceInstanceID string `json:"serviceInstanceID"`

// Network is the reference to the Network to use for this cluster.
// when the field is omitted, A DHCP service will be created in the Power VS server workspace and its private network will be used.
// when the field is omitted, A DHCP service will be created in the Power VS workspace and its private network will be used.
// the DHCP service created network will have the following name format
// 1. in the case of DHCPServer.Name is not set the name will be DHCPSERVER<CLUSTER_NAME>_Private.
// 2. if DHCPServer.Name is set the name will be DHCPSERVER<DHCPServer.Name>_Private.
// when Network.ID is set, its expected that there exist a network in PowerVS workspace with id or else system will give error.
// when Network.Name is set, system will first check for network with Name in PowerVS workspace, if not exist network will be created by DHCP service.
// Network.RegEx is not yet supported and system will ignore the value.
Network IBMPowerVSResourceReference `json:"network"`

// dhcpServer is contains the configuration to be used while creating a new DHCP server in PowerVS workspace.
// when the field is omitted, CLUSTER_NAME will be used as DHCPServer.Name and DHCP server will be created.
// it will automatically create network with name DHCPSERVER<DHCPServer.Name>_Private in PowerVS workspace.
// the default name
// +optional
DHCPServer *DHCPServer `json:"dhcpServer,omitempty"`

// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
// +optional
ControlPlaneEndpoint capiv1beta1.APIEndpoint `json:"controlPlaneEndpoint"`
Expand All @@ -50,46 +63,108 @@ type IBMPowerVSClusterSpec struct {
// supported serviceInstance identifier in PowerVSResource are Name and ID and that can be obtained from IBM Cloud UI or IBM Cloud cli.
// More detail about Power VS service instance.
// https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server
// when omitted system will dynamically create the service instance
// when omitted system will dynamically create the service instance with name CLUSTER_NAME-serviceInstance.
// when ServiceInstance.ID is set, its expected that there exist a service instance in PowerVS workspace with id or else system will give error.
// when ServiceInstance.Name is set, system will first check for service instance with Name in PowerVS workspace, if not exist system will create new instance.
// ServiceInstance.Regex is not yet supported not yet supported and system will ignore the value.
// +optional
ServiceInstance *IBMPowerVSResourceReference `json:"serviceInstance,omitempty"`

// zone is the name of Power VS zone where the cluster will be created
// possible values can be found here https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server.
// when powervs.cluster.x-k8s.io/create-infra=true annotation is set on IBMPowerVSCluster resource,
// 1. it is expected to set the zone, not setting will result in webhook error.
// 2. the zone should have PER capabilities, or else system will give error.
// +optional
Zone *string `json:"zone,omitempty"`

// resourceGroup name under which the resources will be created.
// when omitted default resource group of the account will be used.
// when powervs.cluster.x-k8s.io/create-infra=true annotation is set on IBMPowerVSCluster resource,
// 1. it is expected to set the ResourceGroup.Name, not setting will result in webhook error.
// ServiceInstance.ID and ServiceInstance.Regex is not yet supported and system will ignore the value.
// +optional
ResourceGroup *IBMPowerVSResourceReference `json:"resourceGroup,omitempty"`

// vpc contains information about IBM Cloud VPC resources.
// when omitted system will dynamically create the VPC with name CLUSTER_NAME-vpc.
// when VPC.ID is set, its expected that there exist a VPC with ID or else system will give error.
// when VPC.Name is set, system will first check for VPC with Name, if not exist system will create new VPC.
// when powervs.cluster.x-k8s.io/create-infra=true annotation is set on IBMPowerVSCluster resource,
// 1. it is expected to set the VPC.Region, not setting will result in webhook error.
// +optional
VPC *VPCResourceReference `json:"vpc,omitempty"`

// vpcSubnets contains information about IBM Cloud VPC Subnet resources.
// when omitted system will create the subnets in all the zone corresponding to VPC.Region, with name CLUSTER_NAME-vpcsubnet-ZONE_NAME.
// possible values can be found here https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-creating-power-virtual-server.
// when VPCSubnets[].ID is set, its expected that there exist a subnet with ID or else system will give error.
// when VPCSubnets[].Zone is not set, a random zone is picked from available zones of VPC.Region.
// when VPCSubnets[].Name is not set, system will set name as CLUSTER_NAME-vpcsubnet-INDEX.
// if subnet with name VPCSubnets[].Name not found, system will create new subnet in VPCSubnets[].Zone.
// +optional
VPCSubnets []Subnet `json:"vpcSubnets,omitempty"`

// transitGateway contains information about IBM Cloud TransitGateway
// IBM Cloud TransitGateway helps in establishing network connectivity between IBM Cloud Power VS and VPC infrastructure
// more information about TransitGateway can be found here https://www.ibm.com/products/transit-gateway.
// when TransitGateway.ID is set, its expected that there exist a TransitGateway with ID or else system will give error.
// when TransitGateway.Name is set, system will first check for TransitGateway with Name, if not exist system will create new TransitGateway.
// +optional
TransitGateway *TransitGateway `json:"transitGateway,omitempty"`

// loadBalancers is optional configuration for configuring loadbalancers to control plane or data plane nodes
// loadBalancers is optional configuration for configuring loadbalancers to control plane or data plane nodes.
// when omitted system will create a public loadbalancer with name CLUSTER_NAME-loadbalancer.
// when specified a vpc loadbalancer will be created and controlPlaneEndpoint will be set with associated hostname of loadbalancer.
// when omitted user is expected to set controlPlaneEndpoint.
// ControlPlaneEndpoint will be set with associated hostname of public loadbalancer.
// when LoadBalancers[].ID is set, its expected that there exist a loadbalancer with ID or else system will give error.
// when LoadBalancers[].Name is set, system will first check for loadbalancer with Name, if not exist system will create new loadbalancer.
// +optional
LoadBalancers []VPCLoadBalancerSpec `json:"loadBalancers,omitempty"`

// cosInstance contains options to configure a supporting IBM Cloud COS bucket for this
// cluster - currently used for nodes requiring Ignition
// (https://coreos.github.io/ignition/) for bootstrapping (requires
// BootstrapFormatIgnition feature flag to be enabled).
// when powervs.cluster.x-k8s.io/create-infra=true annotation is set on IBMPowerVSCluster resource and Ignition is set, then
// 1. CosInstance.Name should be set not setting will result in webhook error.
// 2. CosInstance.BucketName should be set not setting will result in webhook error.
// 3. CosInstance.BucketRegion should be set not setting will result in webhook error.
// +optional
CosInstance *CosInstance `json:"cosInstance,omitempty"`

// Ignition defined options related to the bootstrapping systems where Ignition is used.
// +optional
Ignition *Ignition `json:"ignition,omitempty"`
}

// Ignition defines options related to the bootstrapping systems where Ignition is used.
type Ignition struct {
// Version defines which version of Ignition will be used to generate bootstrap data.
//
// +optional
// +kubebuilder:default="2.3"
// +kubebuilder:validation:Enum="2.3";"2.4";"3.0";"3.1";"3.2";"3.3";"3.4"
Version string `json:"version,omitempty"`
}

// DHCPServer contains the DHCP server configurations.
type DHCPServer struct {
// Optional cidr for DHCP private network
Cidr *string `json:"cidr,omitempty"`

// Optional DNS Server for DHCP service
// +kubebuilder:default="1.1.1.1"
DNSServer *string `json:"dnsServer,omitempty"`

// Optional name of DHCP Service. Only alphanumeric characters and dashes are allowed.
Name *string `json:"name,omitempty"`

// Optional id of the existing DHCPServer
ID *string `json:"id,omitempty"`

// Optional indicates if SNAT will be enabled for DHCP service
// +kubebuilder:default=true
Snat *bool `json:"snat,omitempty"`
}

// ResourceReference identifies a resource with id.
Expand Down Expand Up @@ -167,31 +242,38 @@ type IBMPowerVSClusterList struct {

// TransitGateway holds the TransitGateway information.
type TransitGateway struct {
// name of resource.
// +optional
Name *string `json:"name,omitempty"`
ID *string `json:"id,omitempty"`
// id of resource.
// +optional
ID *string `json:"id,omitempty"`
}

// VPCResourceReference is a reference to a specific VPC resource by ID or Name
// Only one of ID or Name may be specified. Specifying more than one will result in
// a validation error.
type VPCResourceReference struct {
// ID of resource
// id of resource.
// +kubebuilder:validation:MinLength=1
// +optional
ID *string `json:"id,omitempty"`

// Name of resource
// name of resource.
// +kubebuilder:validation:MinLength=1
// +optional
Name *string `json:"name,omitempty"`

// IBM Cloud VPC region
// region of IBM Cloud VPC.
// when powervs.cluster.x-k8s.io/create-infra=true annotation is set on IBMPowerVSCluster resource,
// it is expected to set the region, not setting will result in webhook error.
Region *string `json:"region,omitempty"`
}

// CosInstance represents IBM Cloud COS instance.
type CosInstance struct {
// Name defines name of IBM cloud COS instance to be created.
// name defines name of IBM cloud COS instance to be created.
// when IBMPowerVSCluster.Ignition is set
// +kubebuilder:validation:MinLength:=3
// +kubebuilder:validation:MaxLength:=63
// +kubebuilder:validation:Pattern=`^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$`
Expand Down
60 changes: 60 additions & 0 deletions api/v1beta2/ibmpowervscluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1beta2

import (
"strconv"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -74,6 +76,11 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSCluster() (admission.Warnings, err
if err := r.validateIBMPowerVSClusterNetwork(); err != nil {
allErrs = append(allErrs, err)
}

if err := r.validateIBMPowerVSClusterCreateInfraPrereq(); err != nil {
allErrs = append(allErrs, err)
}

if len(allErrs) == 0 {
return nil, nil
}
Expand All @@ -89,3 +96,56 @@ func (r *IBMPowerVSCluster) validateIBMPowerVSClusterNetwork() *field.Error {
}
return nil
}

func (r *IBMPowerVSCluster) validateIBMPowerVSClusterCreateInfraPrereq() *field.Error {
annotations := r.GetAnnotations()
if len(annotations) == 0 {
return nil
}

value, found := annotations[CreateInfrastructureAnnotation]
if !found {
return nil
}

createInfra, err := strconv.ParseBool(value)
if err != nil {
return field.Invalid(field.NewPath("annotations"), r.Annotations, "value of powervs.cluster.x-k8s.io/create-infra should be boolean")
}

if !createInfra {
return nil
}

if r.Spec.Zone == nil {
return field.Invalid(field.NewPath("spec.zone"), r.Spec.Zone, "value of zone is empty")
}

if r.Spec.VPC.Region == nil {
return field.Invalid(field.NewPath("spec.vpc.region"), r.Spec.VPC.Region, "value of VPC region is empty")
}

if r.Spec.ResourceGroup == nil {
return field.Invalid(field.NewPath("spec.resourceGroup"), r.Spec.ResourceGroup, "value of resource group is empty")
}

if r.Spec.Ignition == nil {
return nil
}

// TODO(Phase 1): If ignition is set and these resources are not set, auto create them.
// If ignition is set, make sure to check that CosInstanceName, BucketName and region is set
if r.Spec.CosInstance == nil {
return field.Invalid(field.NewPath("spec.cosInstance"), r.Spec.CosInstance, "ignition is set but value of cosInstance is empty")
}
if r.Spec.CosInstance.Name == "" {
return field.Invalid(field.NewPath("spec.cosInstance.name"), r.Spec.CosInstance, "ignition is set but value of cosInstance name is empty")
}
if r.Spec.CosInstance.BucketName == "" {
return field.Invalid(field.NewPath("spec.cosInstance.bucketName"), r.Spec.CosInstance, "ignition is set but value of bucketName is empty")
}
if r.Spec.CosInstance.BucketRegion == "" {
return field.Invalid(field.NewPath("spec.cosInstance.bucketRegion"), r.Spec.CosInstance, "ignition is set but value of bucketRegion is empty")
}
return nil
}
14 changes: 0 additions & 14 deletions api/v1beta2/ibmpowervsmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,6 @@ type IBMPowerVSMachineSpec struct {
// ProviderID is the unique identifier as specified by the cloud provider.
// +optional
ProviderID *string `json:"providerID,omitempty"`

// Ignition defined options related to the bootstrapping systems where Ignition is used.
// +optional
Ignition *Ignition `json:"ignition,omitempty"`
}

// Ignition defines options related to the bootstrapping systems where Ignition is used.
type Ignition struct {
// Version defines which version of Ignition will be used to generate bootstrap data.
//
// +optional
// +kubebuilder:default="2.3"
// +kubebuilder:validation:Enum="2.3";"3.0";"3.1";"3.2";"3.3";"3.4"
Version string `json:"version,omitempty"`
}

// IBMPowerVSResourceReference is a reference to a specific PowerVS resource by ID, Name or RegEx
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta2/ibmvpccluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ type VPCLoadBalancerSpec struct {
// +optional
Name string `json:"name,omitempty"`

// id of the loadbalancer
// +optional
ID *string `json:"id,omitempty"`

// public indicates that load balancer is public or private
// +kubebuilder:default=true
// +optional
Expand Down
17 changes: 14 additions & 3 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ limitations under the License.

package v1beta2

// APIServerPort is API server port number.
const APIServerPort int32 = 6443
// DefaultAPIServerPort is defuault API server port number.
const DefaultAPIServerPort int32 = 6443

// PowerVSInstanceState describes the state of an IBM Power VS instance.
type PowerVSInstanceState string
Expand Down Expand Up @@ -71,10 +71,21 @@ var (
type TransitGatewayState string

var (
// TransitGatewayStateAvailable is the string representing a transit gateway in available state.
TransitGatewayStateAvailable = TransitGatewayState("available")

// TransitGatewayStateDeletePending is the string representing a transit gateway in deleting state.
TransitGatewayStateDeletePending = TransitGatewayState("deleting")
)

// TransitGatewayConnectionState describes the state of an IBM Transit Gateway connection.
type TransitGatewayConnectionState string

var (
// TransitGatewayConnectionStateAttached is the string representing a transit gateway connection in attached state.
TransitGatewayConnectionStateAttached = TransitGatewayConnectionState("attached")
)

// VPCLoadBalancerState describes the state of the load balancer.
type VPCLoadBalancerState string

Expand Down Expand Up @@ -121,7 +132,7 @@ var (
ResourceTypeTransitGateway = ResourceType("transitGateway")
// ResourceTypeVPC is Power VS network resource.
ResourceTypeVPC = ResourceType("vpc")
// SResourceTypeubnet is VPC subnet resource.
// ResourceTypeSubnet is VPC subnet resource.
ResourceTypeSubnet = ResourceType("subnet")
// ResourceTypeCOSInstance is IBM COS instance resource.
ResourceTypeCOSInstance = ResourceType("cosInstance")
Expand Down
Loading

0 comments on commit d78c229

Please sign in to comment.