Skip to content

Commit

Permalink
feat: support virtualIP.configuration API in handler
Browse files Browse the repository at this point in the history
  • Loading branch information
dkoshkin committed Dec 2, 2024
1 parent 27ad1b6 commit f9b6bd0
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ data:
- name: vip_arp
value: "true"
- name: port
value: '{{ `{{ .ControlPlaneEndpoint.Port }}` }}'
value: '{{ `{{ .Port }}` }}'
- name: vip_nodename
valueFrom:
fieldRef:
Expand All @@ -46,7 +46,7 @@ data:
- name: vip_retryperiod
value: "2"
- name: address
value: '{{ `{{ .ControlPlaneEndpoint.Host }}` }}'
value: '{{ `{{ .Address }}` }}'
- name: prometheus_server
image: ghcr.io/kube-vip/kube-vip:v0.8.3
imagePullPolicy: IfNotPresent
Expand Down
89 changes: 88 additions & 1 deletion docs/content/customization/nutanix/control-plane-endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title = "Control Plane Endpoint"
+++

Configure Control Plane Endpoint. Defines the host IP and port of the CAPX Kubernetes cluster.
Configure Control Plane Endpoint. Defines the host IP and port of the Nutanix Kubernetes cluster.

## Examples

Expand Down Expand Up @@ -51,6 +51,93 @@ spec:
name: kube-vip
namespace: kube-system
spec:
containers:
- name: kube-vip
args:
- manager
env:
- name: port
value: '6443'
- name: address
value: 'x.x.x.x'
...
owner: root:root
path: /etc/kubernetes/manifests/kube-vip.yaml
permissions: "0600"
postKubeadmCommands:
# Only added for clusters version >=v1.29.0
- |-
if [ -f /run/kubeadm/kubeadm.yaml ]; then
sed -i 's#path: /etc/kubernetes/super-admin.conf#path: ...
fi
preKubeadmCommands:
# Only added for clusters version >=v1.29.0
- |-
if [ -f /run/kubeadm/kubeadm.yaml ]; then
sed -i 's#path: /etc/kubernetes/admin.conf#path: ...
fi
```

### Set Control Plane Endpoint and a Different Virtual IP

It is also possible to set a separate virtual IP to be used by kube-vip from the control plane endpoint.
This is useful in VPC setups or other instances
when you have an external floating IP already associated with the virtual IP.

```yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: <NAME>
spec:
topology:
variables:
- name: clusterConfig
value:
nutanix:
controlPlaneEndpoint:
host: x.x.x.x
port: 6443
virtualIP:
configuration:
address: y.y.y.y
```

Applying this configuration will result in the following value being set:

- `NutanixCluster`:

```yaml
spec:
template:
spec:
controlPlaneEndpoint:
host: x.x.x.x
port: 6443
```

- `KubeadmControlPlaneTemplate`

```yaml
spec:
kubeadmConfigSpec:
files:
- content: |
apiVersion: v1
kind: Pod
metadata:
name: kube-vip
namespace: kube-system
spec:
containers:
- name: kube-vip
args:
- manager
env:
- name: port
value: '6443'
- name: address
value: 'y.y.y.y'
...
owner: root:root
path: /etc/kubernetes/manifests/kube-vip.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ spec:
- name: vip_arp
value: "true"
- name: address
value: "{{ .ControlPlaneEndpoint.Host }}"
value: "{{ .Address }}"
- name: port
value: "{{ .ControlPlaneEndpoint.Port }}"
value: "{{ .Port }}"
`
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,79 @@ func Test_GenerateFilesAndCommands(t *testing.T) {
},
},
},
{
name: "should return templated data with both IP and port from virtual IP configuration overrides",
controlPlaneEndpointSpec: v1alpha1.ControlPlaneEndpointSpec{
Host: "10.20.100.10",
Port: 6443,
VirtualIPSpec: &v1alpha1.ControlPlaneVirtualIPSpec{
Configuration: &v1alpha1.ControlPlaneVirtualIPConfiguration{
Address: "172.20.100.10",
Port: 8443,
},
},
},
configMap: &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "default-kube-vip-template",
Namespace: "default",
},
Data: map[string]string{
"data": validKubeVIPTemplate,
},
},
cluster: &clusterv1.Cluster{
Spec: clusterv1.ClusterSpec{
Topology: &clusterv1.Topology{
Version: "v1.28.0",
},
},
},
expectedFiles: []bootstrapv1.File{
{
Content: expectedKubeVIPPodWithOverrides,
Owner: kubeVIPFileOwner,
Path: kubeVIPFilePath,
Permissions: kubeVIPFilePermissions,
},
},
},
{
name: "should return templated data with IP from virtual IP configuration overrides",
controlPlaneEndpointSpec: v1alpha1.ControlPlaneEndpointSpec{
Host: "10.20.100.10",
Port: 8443,
VirtualIPSpec: &v1alpha1.ControlPlaneVirtualIPSpec{
Configuration: &v1alpha1.ControlPlaneVirtualIPConfiguration{
Address: "172.20.100.10",
},
},
},
configMap: &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "default-kube-vip-template",
Namespace: "default",
},
Data: map[string]string{
"data": validKubeVIPTemplate,
},
},
cluster: &clusterv1.Cluster{
Spec: clusterv1.ClusterSpec{
Topology: &clusterv1.Topology{
Version: "v1.28.0",
},
},
},
expectedFiles: []bootstrapv1.File{
{
Content: expectedKubeVIPPodWithOverrides,
Owner: kubeVIPFileOwner,
Path: kubeVIPFilePath,
Permissions: kubeVIPFilePermissions,
},
},
},
}

for idx := range tests {
Expand Down Expand Up @@ -227,9 +300,9 @@ spec:
- name: vip_arp
value: "true"
- name: address
value: "{{ .ControlPlaneEndpoint.Host }}"
value: "{{ .Address }}"
- name: port
value: "{{ .ControlPlaneEndpoint.Port }}"
value: "{{ .Port }}"
`

expectedKubeVIPPod = `
Expand All @@ -253,4 +326,26 @@ spec:
- name: port
value: "6443"
`

expectedKubeVIPPodWithOverrides = `
apiVersion: v1
kind: Pod
metadata:
name: kube-vip
namespace: kube-system
spec:
containers:
- name: kube-vip
image: ghcr.io/kube-vip/kube-vip:v1.1.1
imagePullPolicy: IfNotPresent
args:
- manager
env:
- name: vip_arp
value: "true"
- name: address
value: "172.20.100.10"
- name: port
value: "8443"
`
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package providers

import (
"bytes"
"cmp"
"context"
"fmt"
"text/template"
Expand Down Expand Up @@ -35,11 +36,28 @@ func templateValues(
}

type input struct {
ControlPlaneEndpoint v1alpha1.ControlPlaneEndpointSpec
Address string
Port int32
}

// If specified, use the virtual IP address and/or port,
// otherwise fall back to the control plane endpoint host and port.
address := controlPlaneEndpoint.Host
port := controlPlaneEndpoint.Port
if controlPlaneEndpoint.VirtualIPSpec != nil &&
controlPlaneEndpoint.VirtualIPSpec.Configuration != nil {
address = cmp.Or(
controlPlaneEndpoint.VirtualIPSpec.Configuration.Address,
controlPlaneEndpoint.Host,
)
port = cmp.Or(
controlPlaneEndpoint.VirtualIPSpec.Configuration.Port,
controlPlaneEndpoint.Port,
)
}
templateInput := input{
ControlPlaneEndpoint: controlPlaneEndpoint,
Address: address,
Port: port,
}

var b bytes.Buffer
Expand Down

0 comments on commit f9b6bd0

Please sign in to comment.