Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.

Commit b280f96

Browse files
authored
Merge pull request #773 from cprivitere/emlb-templates
✨ Add EMLB based templates for testing and deployment
2 parents 6d5a0ba + a731c31 commit b280f96

File tree

14 files changed

+562
-163
lines changed

14 files changed

+562
-163
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ e2e-test-templates-v1beta1: $(KUSTOMIZE) ## Generate cluster templates for v1bet
225225
mkdir -p $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/
226226
$(KUSTOMIZE) build $(REPO_ROOT)/templates/experimental-crs-cni --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template.yaml
227227
$(KUSTOMIZE) build $(REPO_ROOT)/templates/experimental-kube-vip-crs-cni --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template-kube-vip.yaml
228+
$(KUSTOMIZE) build $(REPO_ROOT)/templates/experimental-emlb-crs-cni --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template-emlb.yaml
228229
$(KUSTOMIZE) build $(REPO_ROOT)/test/e2e/data/v1beta1/cluster-template-kcp-scale-in --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template-kcp-scale-in.yaml
229230
$(KUSTOMIZE) build $(REPO_ROOT)/test/e2e/data/v1beta1/cluster-template-node-drain --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template-node-drain.yaml
230231
$(KUSTOMIZE) build $(REPO_ROOT)/test/e2e/data/v1beta1/cluster-template-md-remediation --load-restrictor LoadRestrictionsNone > $(TEST_TEMPLATES_TARGET_DIR)/v1beta1/cluster-template-md-remediation.yaml
@@ -282,6 +283,8 @@ generate: ## Generate code
282283

283284
.PHONY: generate-templates
284285
generate-templates: $(KUSTOMIZE) ## Generate cluster templates
286+
$(KUSTOMIZE) build templates/experimental-emlb --load-restrictor LoadRestrictionsNone > templates/cluster-template-emlb.yaml
287+
$(KUSTOMIZE) build templates/experimental-emlb-crs-cni --load-restrictor LoadRestrictionsNone > templates/cluster-template-emlb-crs-cni.yaml
285288
$(KUSTOMIZE) build templates/experimental-kube-vip-crs-cni --load-restrictor LoadRestrictionsNone > templates/cluster-template-kube-vip-crs-cni.yaml
286289
$(KUSTOMIZE) build templates/experimental-kube-vip --load-restrictor LoadRestrictionsNone > templates/cluster-template-kube-vip.yaml
287290
$(KUSTOMIZE) build templates/experimental-crs-cni --load-restrictor LoadRestrictionsNone > templates/cluster-template-crs-cni.yaml

api/v1beta1/packetcluster_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ const (
2727
ClusterFinalizer = "packetcluster.infrastructure.cluster.x-k8s.io"
2828
// NetworkInfrastructureReadyCondition reports of current status of cluster infrastructure.
2929
NetworkInfrastructureReadyCondition clusterv1.ConditionType = "NetworkInfrastructureReady"
30+
// EMLBVIPID is the string used to refer to the EMLB load balancer and VIP Manager type.
31+
EMLBVIPID = "EMLB"
32+
// CPEMID is the string used to refer to the CPEM load balancer and VIP Manager type.
33+
CPEMID = "CPEM"
34+
// KUBEVIPID is the string used to refer to the Kube VIP load balancer and VIP Manager type.
35+
KUBEVIPID = "KUBE_VIP"
3036
)
3137

3238
// VIPManagerType describes if the VIP will be managed by CPEM or kube-vip or Equinix Metal Load Balancer.

controllers/packetcluster_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (r *PacketClusterReconciler) reconcileNormal(ctx context.Context, clusterSc
125125
packetCluster := clusterScope.PacketCluster
126126

127127
switch {
128-
case packetCluster.Spec.VIPManager == emlb.EMLBVIPID:
128+
case packetCluster.Spec.VIPManager == infrav1.EMLBVIPID:
129129
if !packetCluster.Spec.ControlPlaneEndpoint.IsValid() {
130130
// Create new EMLB object
131131
lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], packetCluster.Spec.ProjectID, packetCluster.Spec.Metro)
@@ -135,15 +135,15 @@ func (r *PacketClusterReconciler) reconcileNormal(ctx context.Context, clusterSc
135135
return err
136136
}
137137
}
138-
case packetCluster.Spec.VIPManager == "KUBE_VIP":
138+
case packetCluster.Spec.VIPManager == infrav1.KUBEVIPID:
139139
log.Info("KUBE_VIP VIPManager Detected")
140140
if err := r.PacketClient.EnableProjectBGP(ctx, packetCluster.Spec.ProjectID); err != nil {
141141
log.Error(err, "error enabling bgp for project")
142142
return err
143143
}
144144
}
145145

146-
if packetCluster.Spec.VIPManager != emlb.EMLBVIPID {
146+
if packetCluster.Spec.VIPManager != infrav1.EMLBVIPID {
147147
ipReserv, err := r.PacketClient.GetIPByClusterIdentifier(ctx, clusterScope.Namespace(), clusterScope.Name(), packetCluster.Spec.ProjectID)
148148
switch {
149149
case errors.Is(err, packet.ErrControlPlanEndpointNotFound):
@@ -192,7 +192,7 @@ func (r *PacketClusterReconciler) reconcileDelete(ctx context.Context, clusterSc
192192

193193
packetCluster := clusterScope.PacketCluster
194194

195-
if packetCluster.Spec.VIPManager == emlb.EMLBVIPID {
195+
if packetCluster.Spec.VIPManager == infrav1.EMLBVIPID {
196196
// Create new EMLB object
197197
lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], packetCluster.Spec.ProjectID, packetCluster.Spec.Metro)
198198

controllers/packetmachine_controller.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,8 @@ func (r *PacketMachineReconciler) reconcile(ctx context.Context, machineScope *s
353353
var controlPlaneEndpointAddress string
354354
var cpemLBConfig string
355355
var emlbID string
356-
switch {
357-
case machineScope.PacketCluster.Spec.VIPManager == "CPEM":
356+
switch machineScope.PacketCluster.Spec.VIPManager {
357+
case infrav1.CPEMID, infrav1.KUBEVIPID:
358358
controlPlaneEndpoint, _ = r.PacketClient.GetIPByClusterIdentifier(
359359
ctx,
360360
machineScope.Cluster.Namespace,
@@ -368,7 +368,7 @@ func (r *PacketMachineReconciler) reconcile(ctx context.Context, machineScope *s
368368
addrs = append(addrs, a)
369369
}
370370
controlPlaneEndpointAddress = controlPlaneEndpoint.GetAddress()
371-
case machineScope.PacketCluster.Spec.VIPManager == emlb.EMLBVIPID:
371+
case infrav1.EMLBVIPID:
372372
controlPlaneEndpointAddress = machineScope.Cluster.Spec.ControlPlaneEndpoint.Host
373373
cpemLBConfig = "emlb:///" + machineScope.PacketCluster.Spec.Metro
374374
emlbID = machineScope.PacketCluster.Annotations["equinix.com/loadbalancerID"]
@@ -404,7 +404,7 @@ func (r *PacketMachineReconciler) reconcile(ctx context.Context, machineScope *s
404404
machineScope.SetProviderID(dev.GetId())
405405
machineScope.SetInstanceStatus(infrav1.PacketResourceStatus(dev.GetState()))
406406

407-
if machineScope.PacketCluster.Spec.VIPManager == "KUBE_VIP" {
407+
if machineScope.PacketCluster.Spec.VIPManager == infrav1.KUBEVIPID {
408408
if err := r.PacketClient.EnsureNodeBGPEnabled(ctx, dev.GetId()); err != nil {
409409
// Do not treat an error enabling bgp on machine as fatal
410410
return ctrl.Result{RequeueAfter: time.Second * 20}, fmt.Errorf("failed to enable bgp on machine %s: %w", machineScope.Name(), err)
@@ -426,7 +426,7 @@ func (r *PacketMachineReconciler) reconcile(ctx context.Context, machineScope *s
426426
log.Info("Machine instance is active", "instance-id", machineScope.ProviderID())
427427

428428
switch {
429-
case machineScope.PacketCluster.Spec.VIPManager == "CPEM":
429+
case machineScope.PacketCluster.Spec.VIPManager == infrav1.CPEMID:
430430
controlPlaneEndpoint, _ = r.PacketClient.GetIPByClusterIdentifier(
431431
ctx,
432432
machineScope.Cluster.Namespace,
@@ -441,7 +441,7 @@ func (r *PacketMachineReconciler) reconcile(ctx context.Context, machineScope *s
441441
return ctrl.Result{RequeueAfter: time.Second * 20}, nil
442442
}
443443
}
444-
case machineScope.PacketCluster.Spec.VIPManager == emlb.EMLBVIPID:
444+
case machineScope.PacketCluster.Spec.VIPManager == infrav1.EMLBVIPID:
445445
if machineScope.IsControlPlane() {
446446
// Create new EMLB object
447447
lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], machineScope.PacketCluster.Spec.ProjectID, machineScope.PacketCluster.Spec.Metro)
@@ -543,12 +543,14 @@ func (r *PacketMachineReconciler) reconcileDelete(ctx context.Context, machineSc
543543
return fmt.Errorf("%w: %s", errMissingDevice, packetmachine.Name)
544544
}
545545

546-
if machineScope.PacketCluster.Spec.VIPManager == emlb.EMLBVIPID {
547-
// Create new EMLB object
548-
lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], machineScope.PacketCluster.Spec.ProjectID, packetmachine.Spec.Metro)
546+
if machineScope.PacketCluster.Spec.VIPManager == infrav1.EMLBVIPID {
547+
if machineScope.IsControlPlane() {
548+
// Create new EMLB object
549+
lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], machineScope.PacketCluster.Spec.ProjectID, packetmachine.Spec.Metro)
549550

550-
if err := lb.DeleteLoadBalancerOrigin(ctx, machineScope); err != nil {
551-
return fmt.Errorf("failed to delete load balancer origin: %w", err)
551+
if err := lb.DeleteLoadBalancerOrigin(ctx, machineScope); err != nil {
552+
return fmt.Errorf("failed to delete load balancer origin: %w", err)
553+
}
552554
}
553555
}
554556

docs/experiences/flavors.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,29 @@
44

55
### API Server VIP Management Choice
66

7-
By default CPEM will be used to manage the EIP that serves as the VIP for the api-server. As of v0.6.0 you can choose to use kube-vip to manage the api-server VIP instead of CPEM.
7+
By default CPEM will be used to manage the EIP that serves as the VIP for the api-server. Other flavors include kube-vip and Equinix Metal Load Balancer.
8+
9+
### Choosing Equinix Metal Load Balancer
10+
11+
To use Equinix Metal Load Balancer, when generating the template with `clusterctl`, pass in the `--flavor emlb` flag. For example, your `clusterctl generate` command might look like the following:
12+
13+
```sh
14+
clusterctl generate cluster capi-quickstart \
15+
--kubernetes-version v1.31.0 \
16+
--control-plane-machine-count=3 \
17+
--worker-machine-count=3 \
18+
--infrastructure packet \
19+
--flavor emlb
20+
> capi-quickstart.yaml
21+
```
822

923
### Choosing Kube-VIP
1024

11-
To use kube-vip, when generating the template with `clusterctl`, pass in the `--flavor kube-vip` flag. For example, your `clusterctl generate` command might look like the following:
25+
To use kube-vip, when generating the template with `clusterctl`, pass in the `--flavor kube-vip` flag. For example, your `clusterctl generate` command might look like the following:
1226

1327
```sh
1428
clusterctl generate cluster capi-quickstart \
15-
--kubernetes-version v1.24.0 \
29+
--kubernetes-version v1.31.0 \
1630
--control-plane-machine-count=3 \
1731
--worker-machine-count=3 \
1832
--infrastructure packet \

internal/emlb/emlb.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ const (
4949
loadBalancerPoolIDAnnotation = "equinix.com/loadbalancerpoolID"
5050
// loadBalancerPoolOriginIDAnnotation is the anotation key representing the origin ID of a PacketMachine.
5151
loadBalancerOriginIDAnnotation = "equinix.com/loadbalanceroriginID"
52-
// EMLBVIPID is the stringused to refer to the EMLB load balancer and VIP Manager type.
53-
EMLBVIPID = "EMLB"
5452
// loadbalancerTokenExchangeURL is the default URL to use for Token Exchange to talk to the Equinix Metal Load Balancer API.
5553
loadbalancerTokenExchnageURL = "https://iam.metalctrl.io/api-keys/exchange" //nolint:gosec
5654
)

0 commit comments

Comments
 (0)