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

Commit 87232c2

Browse files
authored
Merge pull request #538 from cprivitere/add-metro-support
🏃 ✨ Add-metro-support
2 parents d6a0fb0 + 2f4c642 commit 87232c2

26 files changed

+190
-50
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ jobs:
197197
E2E_CONF_FILE_SOURCE: "${{ github.workspace }}/test/e2e/config/packet-ci-actions.yaml"
198198
SKIP_IMAGE_BUILD: "1"
199199
MANIFEST_PATH: "../../../out/release"
200-
FACILITY: da11
200+
METRO: da
201201
CONTROLPLANE_NODE_TYPE: c3.medium.x86
202202
WORKER_NODE_TYPE: c3.medium.x86
203203
GINKGO_NODES: "1"
@@ -256,7 +256,7 @@ jobs:
256256
E2E_CONF_FILE_SOURCE: "${{ github.workspace }}/test/e2e/config/packet-ci-actions.yaml"
257257
SKIP_IMAGE_BUILD: "1"
258258
MANIFEST_PATH: "../../../out/release"
259-
FACILITY: da11
259+
METRO: da
260260
CONTROLPLANE_NODE_TYPE: c3.medium.x86
261261
WORKER_NODE_TYPE: c3.medium.x86
262262
GINKGO_NODES: "1"
@@ -315,7 +315,7 @@ jobs:
315315
E2E_CONF_FILE_SOURCE: "${{ github.workspace }}/test/e2e/config/packet-ci-actions.yaml"
316316
SKIP_IMAGE_BUILD: "1"
317317
MANIFEST_PATH: "../../../out/release"
318-
FACILITY: da11
318+
METRO: da
319319
CONTROLPLANE_NODE_TYPE: c3.medium.x86
320320
WORKER_NODE_TYPE: c3.medium.x86
321321
GINKGO_NODES: "1"
@@ -374,7 +374,7 @@ jobs:
374374
E2E_CONF_FILE_SOURCE: "${{ github.workspace }}/test/e2e/config/packet-ci-actions.yaml"
375375
SKIP_IMAGE_BUILD: "1"
376376
MANIFEST_PATH: "../../../out/release"
377-
FACILITY: da11
377+
METRO: da
378378
CONTROLPLANE_NODE_TYPE: c3.medium.x86
379379
WORKER_NODE_TYPE: c3.medium.x86
380380
GINKGO_NODES: "1"
@@ -433,7 +433,7 @@ jobs:
433433
E2E_CONF_FILE_SOURCE: "${{ github.workspace }}/test/e2e/config/packet-ci-actions.yaml"
434434
SKIP_IMAGE_BUILD: "1"
435435
MANIFEST_PATH: "../../../out/release"
436-
FACILITY: da11
436+
METRO: da
437437
CONTROLPLANE_NODE_TYPE: c3.medium.x86
438438
WORKER_NODE_TYPE: c3.medium.x86
439439
GINKGO_NODES: "1"

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ This is the official [cluster-api](https://github.com/kubernetes-sigs/cluster-ap
1010

1111
![Packetbot works hard to keep Kubernetes cluster in a good shape](./docs/banner.png)
1212

13+
## Ugrading to v0.7.X
14+
15+
**IMPORTANT** Before you upgrade, please note that Facilities have been deprecated as of version v0.7.0
16+
17+
* Newly generated cluster yaml files will use Metro by default.
18+
* Facility is still usable, but should be moved away from as soon as you can
19+
* See here for more info on the facility deprecation: [Bye Facilities, Hello (again) Metros](https://feedback.equinixmetal.com/changelog/bye-facilities-hello-again-metros)
20+
* If you would like to upgrade your existing clusters from using facilities to using metros, please work with your Equinix support team to figure out the best course of action. We can also provide some support via our [community Slack](https://slack.equinixmetal.com/) and the [Equinix Helix community site](https://community.equinix.com/).
21+
* The basic process will be to upgrade to v0.7.0, then replace `facility: sv15` with `metro: sv` (insert your correct metro instead of sv, for more information check out our [Metros documentation](https://deploy.equinix.com/developers/docs/metal/locations/metros/)) in your existing PacketCluster and PacketMachine objects and/or yaml files used to reconcile those objects (if you're say, managing them via GitOps)
22+
* The expectation is that if the devices are already in the correct metros you've specified, no disruption will happen to clusters or their devices, however, **as with any breaking change you should verify this outside of production before you upgrade.**
23+
1324
## Requirements
1425

1526
To use the cluster-api to deploy a Kubernetes cluster to Equinix Metal, you need the following:

api/v1alpha3/packetcluster_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ type PacketClusterSpec struct {
3030
ProjectID string `json:"projectID"`
3131

3232
// Facility represents the Packet facility for this cluster
33+
// +optional
3334
Facility string `json:"facility,omitempty"`
3435

36+
// Metro represents the Packet metro for this cluster
37+
// +optional
38+
Metro string `json:"metro,omitempty"`
39+
3540
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
3641
// +optional
3742
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`

api/v1alpha3/packetmachine_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ type PacketMachineSpec struct {
4040
// +optional
4141
Facility string `json:"facility,omitempty"`
4242

43+
// Metro represents the Packet metro for this cluster
44+
// Override from the PacketCluster spec.
45+
// +optional
46+
Metro string `json:"metro,omitempty"`
47+
4348
// IPXEUrl can be used to set the pxe boot url when using custom OSes with this provider.
4449
// Note that OS should also be set to "custom_ipxe" if using this value.
4550
// +optional

api/v1alpha3/zz_generated.conversion.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/packetcluster_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ type PacketClusterSpec struct {
3535
ProjectID string `json:"projectID"`
3636

3737
// Facility represents the Packet facility for this cluster
38+
// +optional
3839
Facility string `json:"facility,omitempty"`
3940

41+
// Metro represents the Packet metro for this cluster
42+
// +optional
43+
Metro string `json:"metro,omitempty"`
44+
4045
// ControlPlaneEndpoint represents the endpoint used to communicate with the control plane.
4146
// +optional
4247
ControlPlaneEndpoint clusterv1.APIEndpoint `json:"controlPlaneEndpoint"`

api/v1beta1/packetcluster_webhook.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ func (c *PacketCluster) Default() {
4747
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
4848
func (c *PacketCluster) ValidateCreate() error {
4949
clusterlog.Info("validate create", "name", c.Name)
50+
allErrs := field.ErrorList{}
51+
52+
// Must have either one of Metro or Facility
53+
if len(c.Spec.Facility) == 0 && len(c.Spec.Metro) == 0 {
54+
allErrs = append(allErrs,
55+
field.Invalid(field.NewPath("spec", "Metro"),
56+
c.Spec.Metro, "field is required"),
57+
)
58+
}
59+
60+
if len(allErrs) > 0 {
61+
return apierrors.NewInvalid(GroupVersion.WithKind("PacketCluster").GroupKind(), c.Name, allErrs)
62+
}
5063

5164
return nil
5265
}
@@ -64,17 +77,26 @@ func (c *PacketCluster) ValidateUpdate(oldRaw runtime.Object) error {
6477
)
6578
}
6679

67-
if !reflect.DeepEqual(c.Spec.Facility, old.Spec.Facility) {
80+
if !reflect.DeepEqual(c.Spec.VIPManager, old.Spec.VIPManager) {
6881
allErrs = append(allErrs,
69-
field.Invalid(field.NewPath("spec", "Facility"),
70-
c.Spec.Facility, "field is immutable"),
82+
field.Invalid(field.NewPath("spec", "VIPManager"),
83+
c.Spec.VIPManager, "field is immutable"),
7184
)
7285
}
7386

74-
if !reflect.DeepEqual(c.Spec.VIPManager, old.Spec.VIPManager) {
87+
// Must have at least Metro or Facility specified
88+
if len(c.Spec.Facility) == 0 && len(c.Spec.Metro) == 0 {
7589
allErrs = append(allErrs,
76-
field.Invalid(field.NewPath("spec", "VIPManager"),
77-
c.Spec.VIPManager, "field is immutable"),
90+
field.Invalid(field.NewPath("spec", "Metro"),
91+
c.Spec.Metro, "Metro is required"),
92+
)
93+
}
94+
95+
// Must have only one of Metro or Facility
96+
if len(c.Spec.Facility) > 0 && len(c.Spec.Metro) > 0 {
97+
allErrs = append(allErrs,
98+
field.Invalid(field.NewPath("spec", "Facility"),
99+
c.Spec.Facility, "Metro and Facility are mutually exclusive, Metro is recommended"),
78100
)
79101
}
80102

api/v1beta1/packetmachine_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ type PacketMachineSpec struct {
6363
// +optional
6464
Facility string `json:"facility,omitempty"`
6565

66+
// Metro represents the Packet metro for this machine
67+
// Override from the PacketCluster spec.
68+
// +optional
69+
Metro string `json:"metro,omitempty"`
70+
6671
// IPXEUrl can be used to set the pxe boot url when using custom OSes with this provider.
6772
// Note that OS should also be set to "custom_ipxe" if using this value.
6873
// +optional

api/v1beta1/packetmachine_webhook.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,29 @@ func (m *PacketMachine) ValidateCreate() error {
4848

4949
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
5050
func (m *PacketMachine) ValidateUpdate(old runtime.Object) error {
51+
machineLog.Info("validate update", "name", m.Name)
52+
var allErrs field.ErrorList
53+
54+
// Must have only one of Metro or Facility specified
55+
if len(m.Spec.Facility) > 0 && len(m.Spec.Metro) > 0 {
56+
allErrs = append(allErrs,
57+
field.Invalid(field.NewPath("spec", "Facility"),
58+
m.Spec.Facility, "Metro and Facility field are mutually exclusive"),
59+
)
60+
}
61+
5162
newPacketMachine, err := runtime.DefaultUnstructuredConverter.ToUnstructured(m)
5263
if err != nil {
53-
return apierrors.NewInvalid(GroupVersion.WithKind("PacketMachine").GroupKind(), m.Name, field.ErrorList{
54-
field.InternalError(nil, errors.Wrap(err, "failed to convert new PacketMachine to unstructured object")),
55-
})
64+
allErrs = append(allErrs,
65+
field.InternalError(nil, errors.Wrap(err,
66+
"failed to convert new PacketMachine to unstructured object")))
5667
}
68+
5769
oldPacketMachine, err := runtime.DefaultUnstructuredConverter.ToUnstructured(old)
5870
if err != nil {
59-
return apierrors.NewInvalid(GroupVersion.WithKind("PacketMachine").GroupKind(), m.Name, field.ErrorList{
60-
field.InternalError(nil, errors.Wrap(err, "failed to convert old PacketMachine to unstructured object")),
61-
})
71+
allErrs = append(allErrs,
72+
field.InternalError(nil, errors.Wrap(err,
73+
"failed to convert old PacketMachine to unstructured object")))
6274
}
6375

6476
newPacketMachineSpec, _ := newPacketMachine["spec"].(map[string]interface{})
@@ -72,13 +84,26 @@ func (m *PacketMachine) ValidateUpdate(old runtime.Object) error {
7284
delete(oldPacketMachineSpec, "tags")
7385
delete(newPacketMachineSpec, "tags")
7486

87+
// allow changes to facility
88+
delete(oldPacketMachineSpec, "facility")
89+
delete(newPacketMachineSpec, "facility")
90+
91+
// allow changes to metro
92+
delete(oldPacketMachineSpec, "metro")
93+
delete(newPacketMachineSpec, "metro")
94+
7595
if !reflect.DeepEqual(oldPacketMachineSpec, newPacketMachineSpec) {
76-
return apierrors.NewInvalid(GroupVersion.WithKind("PacketMachine").GroupKind(), m.Name, field.ErrorList{
77-
field.Forbidden(field.NewPath("spec"), "cannot be modified"),
78-
})
96+
allErrs = append(allErrs,
97+
field.Invalid(field.NewPath("spec"),
98+
m.Spec, "cannot be modified"),
99+
)
79100
}
80101

81-
return nil
102+
if len(allErrs) == 0 {
103+
return nil
104+
}
105+
106+
return apierrors.NewInvalid(GroupVersion.WithKind("PacketMachine").GroupKind(), m.Name, allErrs)
82107
}
83108

84109
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.

config/crd/bases/infrastructure.cluster.x-k8s.io_packetclusters.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ spec:
6464
facility:
6565
description: Facility represents the Packet facility for this cluster
6666
type: string
67+
metro:
68+
description: Metro represents the Packet metro for this cluster
69+
type: string
6770
projectID:
6871
description: ProjectID represents the Packet Project where this cluster
6972
will be placed into
@@ -139,6 +142,9 @@ spec:
139142
facility:
140143
description: Facility represents the Packet facility for this cluster
141144
type: string
145+
metro:
146+
description: Metro represents the Packet metro for this cluster
147+
type: string
142148
projectID:
143149
description: ProjectID represents the Packet Project where this cluster
144150
will be placed into

0 commit comments

Comments
 (0)