From e6c03563d63f4ace31fc307f8a0f8fba9846353a Mon Sep 17 00:00:00 2001 From: Lukas Metzner Date: Tue, 29 Oct 2024 12:40:54 +0100 Subject: [PATCH] feat(instance): add label to distinguish servers from Cloud and Robot (#764) This update to the HCCM introduces a new label for Kubernetes nodes: `instance.hetzner.cloud/provided-by`. This label will be automatically applied to nodes, indicating their origin as either: - `robot` for dedicated servers - `cloud` for cloud-based virtual machines With this features other components (e.g. csi-driver) can fine-tune their deployment requirements. --- README.md | 1 + docs/robot.md | 3 +++ hcloud/instances.go | 10 ++++++++++ hcloud/instances_test.go | 6 ++++++ tests/e2e/cloud_test.go | 13 +++++++------ tests/e2e/robot_test.go | 7 ++++--- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bd563cef7..f973f2584 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ metadata: node.kubernetes.io/instance-type: cx22 topology.kubernetes.io/region: fsn1 topology.kubernetes.io/zone: fsn1-dc8 + instance.hetzner.cloud/provided-by: cloud name: node spec: podCIDR: 10.244.0.0/24 diff --git a/docs/robot.md b/docs/robot.md index 8c7385b4e..76dc84f01 100644 --- a/docs/robot.md +++ b/docs/robot.md @@ -47,6 +47,9 @@ The Node controller adds information about the server to the Node object. The va - `topology.kubernetes.io/zone` - Examples: `hel1-dc5` `fsn1-dc16` - We use the lowercase variant of the location to match the Cloud Datacenters + - `instance.hetzner.cloud/provided-by` + - Examples: `robot` `cloud` + - We detect if the node is a Robot server or Cloud VM and set the label accordingly - Provider ID - We set the field `Node.spec.providerID` to identify the Robot server after the initial adoption. - The format is `hrobot://$SERVER_NUMBER`, but we can also read from the deprecated format used by [syself/hetzner-cloud-controller-manager](https://github.com/syself/hetzner-cloud-controller-manager): `hcloud://bm-$SERVER_NUMBER` diff --git a/hcloud/instances.go b/hcloud/instances.go index e43d4564c..fa32023de 100644 --- a/hcloud/instances.go +++ b/hcloud/instances.go @@ -33,6 +33,10 @@ import ( "github.com/hetznercloud/hcloud-go/v2/hcloud" ) +const ( + ProvidedBy = "instance.hetzner.cloud/provided-by" +) + type instances struct { client *hcloud.Client robotClient robot.Client @@ -273,6 +277,9 @@ func (s hcloudServer) Metadata(addressFamily config.AddressFamily, networkID int NodeAddresses: hcloudNodeAddresses(addressFamily, networkID, s.Server), Zone: s.Datacenter.Name, Region: s.Datacenter.Location.Name, + AdditionalLabels: map[string]string{ + ProvidedBy: "cloud", + }, }, nil } @@ -299,5 +306,8 @@ func (s robotServer) Metadata(addressFamily config.AddressFamily, _ int64) (*clo NodeAddresses: robotNodeAddresses(addressFamily, s.Server), Zone: getZoneOfRobotServer(s.Server), Region: getRegionOfRobotServer(s.Server), + AdditionalLabels: map[string]string{ + ProvidedBy: "robot", + }, }, nil } diff --git a/hcloud/instances_test.go b/hcloud/instances_test.go index b49fe145a..ec4d12b97 100644 --- a/hcloud/instances_test.go +++ b/hcloud/instances_test.go @@ -361,6 +361,9 @@ func TestInstances_InstanceMetadata(t *testing.T) { }, Zone: "Test DC", Region: "Test Location", + AdditionalLabels: map[string]string{ + "instance.hetzner.cloud/provided-by": "cloud", + }, } if !reflect.DeepEqual(metadata, expectedMetadata) { @@ -405,6 +408,9 @@ func TestInstances_InstanceMetadataRobotServer(t *testing.T) { }, Zone: "nbg1-dc1", Region: "nbg1", + AdditionalLabels: map[string]string{ + "instance.hetzner.cloud/provided-by": "robot", + }, } if !reflect.DeepEqual(metadata, expectedMetadata) { diff --git a/tests/e2e/cloud_test.go b/tests/e2e/cloud_test.go index d62c22f16..04eb8caa7 100644 --- a/tests/e2e/cloud_test.go +++ b/tests/e2e/cloud_test.go @@ -35,12 +35,13 @@ func TestNodeSetCorrectNodeLabelsAndIPAddresses(t *testing.T) { labels := node.Labels expectedLabels := map[string]string{ - "node.kubernetes.io/instance-type": server.ServerType.Name, - "topology.kubernetes.io/region": server.Datacenter.Location.Name, - "topology.kubernetes.io/zone": server.Datacenter.Name, - "kubernetes.io/hostname": server.Name, - "kubernetes.io/os": "linux", - "kubernetes.io/arch": "amd64", + "node.kubernetes.io/instance-type": server.ServerType.Name, + "topology.kubernetes.io/region": server.Datacenter.Location.Name, + "topology.kubernetes.io/zone": server.Datacenter.Name, + "kubernetes.io/hostname": server.Name, + "kubernetes.io/os": "linux", + "kubernetes.io/arch": "amd64", + "instance.hetzner.cloud/provided-by": "cloud", } for expectedLabel, expectedValue := range expectedLabels { if labelValue, ok := labels[expectedLabel]; !ok || labelValue != expectedValue { diff --git a/tests/e2e/robot_test.go b/tests/e2e/robot_test.go index cb5a15789..200169e32 100644 --- a/tests/e2e/robot_test.go +++ b/tests/e2e/robot_test.go @@ -41,9 +41,10 @@ func TestNodeSetCorrectNodeLabelsAndIPAddressesRobot(t *testing.T) { labels := node.Labels expectedLabels := map[string]string{ - "kubernetes.io/hostname": server.Name, - "kubernetes.io/os": "linux", - "kubernetes.io/arch": "amd64", + "kubernetes.io/hostname": server.Name, + "kubernetes.io/os": "linux", + "kubernetes.io/arch": "amd64", + "instance.hetzner.cloud/provided-by": "robot", } for expectedLabel, expectedValue := range expectedLabels { assert.Equal(t, expectedValue, labels[expectedLabel], "node does not have expected label %s", expectedLabel)