Skip to content

Commit

Permalink
Add HAProxyLoadBalancer CRD
Browse files Browse the repository at this point in the history
This patch introduces the HAProxyLoadBalancer CRD in order to support
a new controller for deploying an HAProxy load balancer so that CAPV
may support HA clusters.
  • Loading branch information
akutz committed Dec 29, 2019
1 parent 6235d06 commit 2531e91
Show file tree
Hide file tree
Showing 23 changed files with 2,336 additions and 874 deletions.
14 changes: 8 additions & 6 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
.git
.github
.git/
.github/
.vscode
.dockerignore
.gitignore
.golangci.yml
.markdownlintrc
*.out
bin/
build/
hack/.bin/
hack/tools/bin/
hack/tools/haproxy/
out/
docs/
scripts/
**/.md
/*.test
/cluster-api-provider-vsphere
/examples/provider-components/provider-components*.yaml
*.test
cluster-api-provider-vsphere
examples/provider-components/provider-components*.yaml
test/
4 changes: 4 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ resources:
- group: infrastructure
version: v1alpha3
kind: VSphereVM
- group: infrastructure
version: v1alpha3
kind: HAProxyLoadBalancer

163 changes: 163 additions & 0 deletions api/v1alpha3/haproxyloadbalancer_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha3

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// HAProxyLoadBalancerFinalizer allows a reconciler to clean up
// resources associated with an HAProxyLoadBalancer before removing
// it from the API server.
HAProxyLoadBalancerFinalizer = "haproxyloadbalancer.infrastructure.cluster.x-k8s.io"
)

// HAProxyLoadBalancerSpec defines the desired state of HAProxyLoadBalancer.
type HAProxyLoadBalancerSpec struct {
// APIEndpoint is the address and port with which the load balancer API
// service may be accessed.
// If omitted then the VirtualMachineConfiguration field is required in
// order to deploy a new load balancer.
// +optional
APIEndpoint APIEndpoint `json:"apiEndpoint,omitempty"`

// Ports is a list of one or more pairs of ports on which the load balancer
// listens for incoming traffic and the ports on the backend to which the
// traffic is transmitted.
Ports []LoadBalancerPort `json:"ports"`

// Selector is used to identify the control-plane Machine resources that
// will be the backend servers for this load balancer.
Selector metav1.LabelSelector `json:"selector"`

// CACertificateRef is a reference to a Secret resource that contains the
// following keys:
// * ca.crt - The PEM-encoded, public key for a CA certificate
// * ca.key - The PEM-encoded, private key for a CA certificate
//
// If unspecified, the Secret's Namespace defaults to
// HAProxyLoadBalancer.Namespace.
//
// If unspecified, the Secret's Name defaults to
// HAProxyLoadBalancer.Name+"-ca".
//
// When using an existing load balancer only the public key is required,
// however, if the private key is present as well and the
// ClientCertificateRef does not exist or contain a valid client
// certificate, then the public and private key in this Secret will be used
// to generate a valid, client certifiate for an existing load balancer.
//
// When provisioning a new load balancer this Secret must contain both
// a public *and* private key. If the Secret does not exist then a new
// Secret will be generated with a new CA key pair. If the Secret exists
// but does not contain a valid CA key pair then a new key pair will be
// generated and the Secret will be updated.
//
// If an existing load balancer is used then the Secret need only to contain
// the CA's public key.
CACertificateRef corev1.SecretReference `json:"caCertificateRef"`

// ClientCredentialsRef is a reference to a Secret resource that contains
// the following keys:
// * client.crt - A PEM-encoded, public key for a client certificate
// used to access the load balancer's API server
// * client.key - A PEM-encoded, private key for a client certificate
// used to access the load balancer's API server
// * username - The username used to access the load balancer's API
// server
// * password - The password used to access the load balancer's API
// server
//
// If unspecified, the Secret's Namespace defaults to
// HAProxyLoadBalancer.Namespace.
//
// If unspecified, the Secret's Name defaults to
// HAProxyLoadBalancer.Name+"-client".
//
// This Secret must contain both a public *and* private key. If the Secret
// does not exist then a new Secret will be generated with a new client
// certificate key pair using the CA from CACertificateRef.
//
// If the Secret exists but does not contain a valid client certificate key
// pair, then a new client certificate key pair will be generated using the
// CA from CACertificateRef.
//
// When the username or password fields are empty, they both default to
// "guest". The HAProxy load balancer OVA built from the CAPV repository
// uses mutual certificate validation (client certificates) to control
// access to the load balancer's API server. However, a username and
// password are still required, even though they provide no actual access
// control.
ClientCredentialsRef corev1.SecretReference `json:"clientCredentialsRef"`

// VirtualMachineConfiguration is optional information used to deploy a new
// load VM.
// If omitted then the APIEndpoint field is required to point to an existing
// load balancer.
// +omitempty
VirtualMachineConfiguration *VirtualMachineCloneSpec `json:"virtualMachineConfiguration,omitempty"`
}

// HAProxyLoadBalancerStatus defines the observed state of HAProxyLoadBalancer.
type HAProxyLoadBalancerStatus struct {
// Ready indicates whether or not the load balancer is ready.
//
// This field is required as part of the Portable Load Balancer model and is
// inspected via an unstructured reader by other controllers to determine
// the status of the load balancer.
//
// +optional
Ready bool `json:"ready,omitempty"`

// Address is the IP address or DNS name of the load balancer.
//
// This field is required as part of the Portable Load Balancer model and is
// inspected via an unstructured reader by other controllers to determine
// the status of the load balancer.
//
// +optional
Address string `json:"address,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=haproxyloadbalancers,scope=Namespaced
// +kubebuilder:storageversion
// +kubebuilder:subresource:status

// HAProxyLoadBalancer is the Schema for the haproxyloadbalancers API
type HAProxyLoadBalancer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec HAProxyLoadBalancerSpec `json:"spec,omitempty"`
Status HAProxyLoadBalancerStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// HAProxyLoadBalancerList contains a list of HAProxyLoadBalancer
type HAProxyLoadBalancerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []HAProxyLoadBalancer `json:"items"`
}

func init() {
SchemeBuilder.Register(&HAProxyLoadBalancer{}, &HAProxyLoadBalancerList{})
}
71 changes: 70 additions & 1 deletion api/v1alpha3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,63 @@ const (
ValueReady = "true"
)

// VirtualMachineCloneSpec is information used to clone a virtual machine.
type VirtualMachineCloneSpec struct {
// Template is the name or inventory path of the template used to clone
// the virtual machine.
Template string `json:"template"`

// Server is the IP address or FQDN of the vSphere server on which
// the virtual machine is created/located.
// +optional
Server string `json:"server,omitempty"`

// Datacenter is the name or inventory path of the datacenter in which the
// virtual machine is created/located.
// +optional
Datacenter string `json:"datacenter,omitempty"`

// Folder is the name or inventory path of the folder in which the
// virtual machine is created/located.
// +optional
Folder string `json:"folder,omitempty"`

// Datastore is the name or inventory path of the datastore in which the
// virtual machine is created/located.
// +optional
Datastore string `json:"datastore,omitempty"`

// ResourcePool is the name or inventory path of the resource pool in which
// the virtual machine is created/located.
// +optional
ResourcePool string `json:"resourcePool,omitempty"`

// Network is the network configuration for this machine's VM.
Network NetworkSpec `json:"network"`

// NumCPUs is the number of virtual processors in a virtual machine.
// Defaults to the eponymous property value in the template from which the
// virtual machine is cloned.
// +optional
NumCPUs int32 `json:"numCPUs,omitempty"`
// NumCPUs is the number of cores among which to distribute CPUs in this
// virtual machine.
// Defaults to the eponymous property value in the template from which the
// virtual machine is cloned.
// +optional
NumCoresPerSocket int32 `json:"numCoresPerSocket,omitempty"`
// MemoryMiB is the size of a virtual machine's memory, in MiB.
// Defaults to the eponymous property value in the template from which the
// virtual machine is cloned.
// +optional
MemoryMiB int64 `json:"memoryMiB,omitempty"`
// DiskGiB is the size of a virtual machine's disk, in GiB.
// Defaults to the eponymous property value in the template from which the
// virtual machine is cloned.
// +optional
DiskGiB int32 `json:"diskGiB,omitempty"`
}

// VSphereMachineTemplateResource describes the data needed to create a VSphereMachine from a template
type VSphereMachineTemplateResource struct {
metav1.TypeMeta `json:",inline"`
Expand Down Expand Up @@ -63,7 +120,7 @@ type APIEndpoint struct {
Host string `json:"host"`

// The port on which the API server is serving.
Port int `json:"port"`
Port int32 `json:"port"`
}

// IsZero returns true if either the host or the port are zero values.
Expand Down Expand Up @@ -228,3 +285,15 @@ type VirtualMachine struct {
// Network is the status of the VM's network devices.
Network []NetworkStatus `json:"network"`
}

// LoadBalancerPort defines the pair of frontend and backend ports used by
// the load balancer.
type LoadBalancerPort struct {
// Ingress is the port on which a load balancer listens for incoming
// traffic.
Ingress int32 `json:"ingress"`

// Egress is the port to which a load balancer transmits traffic to
// backend servers.
Egress int32 `json:"egress"`
}
9 changes: 9 additions & 0 deletions api/v1alpha3/vspherecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha3

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"sigs.k8s.io/cluster-api-provider-vsphere/api/v1alpha3/cloudprovider"
Expand Down Expand Up @@ -46,6 +47,14 @@ type VSphereClusterSpec struct {
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
// +optional
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"`

// LoadBalancerRef may be used to enable a control plane load balancer
// for this cluster.
// When a LoadBalancerRef is provided, the VSphereCluster.Status.Ready field
// will not be true until the referenced resource is Status.Ready and has a
// non-empty Status.Address value.
// +optional
LoadBalancerRef *corev1.ObjectReference `json:"loadBalancerRef,omitempty"`
}

// VSphereClusterStatus defines the observed state of VSphereClusterSpec
Expand Down
46 changes: 2 additions & 44 deletions api/v1alpha3/vspheremachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,43 +31,12 @@ const (

// VSphereMachineSpec defines the desired state of VSphereMachine
type VSphereMachineSpec struct {
VirtualMachineCloneSpec `json:",inline"`

// ProviderID is the virtual machine's BIOS UUID formated as
// vsphere://12345678-1234-1234-1234-123456789abc
// +optional
ProviderID *string `json:"providerID,omitempty"`

// Template is the name, inventory path, or instance UUID of the template
// used to clone new machines.
Template string `json:"template"`

// Datacenter is the name or inventory path of the datacenter where this
// machine's VM is created/located.
Datacenter string `json:"datacenter"`

// Network is the network configuration for this machine's VM.
Network NetworkSpec `json:"network"`

// NumCPUs is the number of virtual processors in a virtual machine.
// Defaults to the analogue property value in the template from which this
// machine is cloned.
// +optional
NumCPUs int32 `json:"numCPUs,omitempty"`
// NumCPUs is the number of cores among which to distribute CPUs in this
// virtual machine.
// Defaults to the analogue property value in the template from which this
// machine is cloned.
// +optional
NumCoresPerSocket int32 `json:"numCoresPerSocket,omitempty"`
// MemoryMiB is the size of a virtual machine's memory, in MiB.
// Defaults to the analogue property value in the template from which this
// machine is cloned.
// +optional
MemoryMiB int64 `json:"memoryMiB,omitempty"`
// DiskGiB is the size of a virtual machine's disk, in GiB.
// Defaults to the analogue property value in the template from which this
// machine is cloned.
// +optional
DiskGiB int32 `json:"diskGiB,omitempty"`
}

// VSphereMachineStatus defines the observed state of VSphereMachine
Expand All @@ -79,17 +48,6 @@ type VSphereMachineStatus struct {
// Addresses contains the VSphere instance associated addresses.
Addresses []v1.NodeAddress `json:"addresses,omitempty"`

// TaskRef is a managed object reference to a Task related to the machine.
// This value is set automatically at runtime and should not be set or
// modified by users.
// +optional
TaskRef string `json:"taskRef,omitempty"`

// Network returns the network status for each of the machine's configured
// network interfaces.
// +optional
Network []NetworkStatus `json:"networkStatus,omitempty"`

// ErrorReason will be set in the event that there is a terminal problem
// reconciling the Machine and will contain a succinct value suitable
// for machine interpretation.
Expand Down
Loading

0 comments on commit 2531e91

Please sign in to comment.