diff --git a/api/v1beta1/hcloudremediation_types.go b/api/v1beta1/hcloudremediation_types.go index 07d1920b9..695b14519 100644 --- a/api/v1beta1/hcloudremediation_types.go +++ b/api/v1beta1/hcloudremediation_types.go @@ -21,11 +21,6 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ) -const ( - // HCloudRebootAnnotation indicates that a bare metal host object should be rebooted. - HCloudRebootAnnotation = "reboot.hcloud.infrastructure.cluster.x-k8s.io" -) - // HCloudRemediationSpec defines the desired state of HCloudRemediation. type HCloudRemediationSpec struct { // Strategy field defines remediation strategy. diff --git a/api/v1beta1/hetznerbaremetalhost_types.go b/api/v1beta1/hetznerbaremetalhost_types.go index 801ded913..496f3ffff 100644 --- a/api/v1beta1/hetznerbaremetalhost_types.go +++ b/api/v1beta1/hetznerbaremetalhost_types.go @@ -21,7 +21,6 @@ import ( "crypto/sha256" "encoding/json" "fmt" - "strings" "time" corev1 "k8s.io/api/core/v1" @@ -46,10 +45,10 @@ const ( // WipeDiskAnnotation indicates which Disks (WWNs) to erase before provisioning // The value is a list of WWNS or "all". - WipeDiskAnnotation = "wipedisk.hetznerbaremetalhost.infrastructure.cluster.x-k8s.io" + WipeDiskAnnotation = "capi.syself.com/wipe-disk" // IgnoreCheckDiskAnnotation indicates that the machine should get provisioned, even if CheckDisk fails. - IgnoreCheckDiskAnnotation = "ignore-cd.hetznerbaremetalhost.infrastructure.cluster.x-k8s.io" // max length is 63 chars. + IgnoreCheckDiskAnnotation = "capi.syself.com/ignore-check-disk" ) // RootDeviceHints holds the hints for specifying the storage location @@ -602,7 +601,7 @@ func (host *HetznerBareMetalHost) ClearRebootAnnotations() { } func isRebootAnnotation(annotation string) bool { - return strings.HasPrefix(annotation, RebootAnnotation+"/") || annotation == RebootAnnotation + return annotation == RebootAnnotation } //+kubebuilder:object:root=true diff --git a/api/v1beta1/hetznerbaremetalhost_types_test.go b/api/v1beta1/hetznerbaremetalhost_types_test.go index 9b7d205fa..2f449d2a9 100644 --- a/api/v1beta1/hetznerbaremetalhost_types_test.go +++ b/api/v1beta1/hetznerbaremetalhost_types_test.go @@ -406,8 +406,6 @@ var _ = Describe("Test ClearRebootAnnotations", func() { expectAnnotations map[string]string } - secondRebootAnnotation := RebootAnnotation + "/" - DescribeTable("Test ClearRebootAnnotations", func(tc testCaseClearRebootAnnotations) { host := HetznerBareMetalHost{} @@ -417,10 +415,6 @@ var _ = Describe("Test ClearRebootAnnotations", func() { Expect(host.Annotations).Should(Equal(tc.expectAnnotations)) }, - Entry("has reboot annotation - one annotation in list", testCaseClearRebootAnnotations{ - currentAnnotations: map[string]string{secondRebootAnnotation: "reboot", RebootAnnotation: "reboot"}, - expectAnnotations: map[string]string{}, - }), Entry("has multiple reboot annotations - no other annotation in list", testCaseClearRebootAnnotations{ currentAnnotations: map[string]string{RebootAnnotation: "reboot"}, expectAnnotations: map[string]string{}, @@ -430,7 +424,7 @@ var _ = Describe("Test ClearRebootAnnotations", func() { expectAnnotations: map[string]string{"other": "annotation"}, }), Entry("has multiple reboot annotations - multiple annotations in list", testCaseClearRebootAnnotations{ - currentAnnotations: map[string]string{secondRebootAnnotation: "reboot", "other": "annotation", RebootAnnotation: "reboot"}, + currentAnnotations: map[string]string{"other": "annotation", RebootAnnotation: "reboot"}, expectAnnotations: map[string]string{"other": "annotation"}, }), Entry("has no reboot annotation", testCaseClearRebootAnnotations{ @@ -456,7 +450,7 @@ var _ = Describe("Test ClearRebootAnnotations", func() { }), Entry("reboot prefix", testCaseClearRebootAnnotations{ annotation: RebootAnnotation + "/" + "suffix", - expectBool: true, + expectBool: false, }), Entry("other annotation", testCaseClearRebootAnnotations{ annotation: "different/annotation", diff --git a/api/v1beta1/hetznerbaremetalremediation_types.go b/api/v1beta1/hetznerbaremetalremediation_types.go index 8fb7967f0..4dd47d881 100644 --- a/api/v1beta1/hetznerbaremetalremediation_types.go +++ b/api/v1beta1/hetznerbaremetalremediation_types.go @@ -22,12 +22,12 @@ import ( const ( // RebootAnnotation indicates that a bare metal host object should be rebooted. - RebootAnnotation = "reboot.hetznerbaremetalhost.infrastructure.cluster.x-k8s.io" + RebootAnnotation = "capi.syself.com/reboot" // PermanentErrorAnnotation indicates that the bare metal host has an error which needs to be resolved manually. // After the permanent error the annotation got removed (usually by a human), the controller removes // ErrorType, ErrorCount and ErrorMessages, so that the hbmh will be usable again. - PermanentErrorAnnotation = "error.hetznerbaremetalhost.infrastructure.cluster.x-k8s.io" + PermanentErrorAnnotation = "capi.syself.com/permanent-error" ) // HetznerBareMetalRemediationSpec defines the desired state of HetznerBareMetalRemediation. diff --git a/api/v1beta1/hetznercluster_webhook.go b/api/v1beta1/hetznercluster_webhook.go index 3904e4595..72c0746e2 100644 --- a/api/v1beta1/hetznercluster_webhook.go +++ b/api/v1beta1/hetznercluster_webhook.go @@ -74,10 +74,7 @@ func (r *HetznerCluster) ValidateCreate() (admission.Warnings, error) { hetznerclusterlog.V(1).Info("validate create", "name", r.Name) var allErrs field.ErrorList - allowEmptyControlPlaneAddress := false - if r.Annotations != nil { - allowEmptyControlPlaneAddress = r.Annotations[AllowEmptyControlPlaneAddressAnnotation] == "true" - } + allowEmptyControlPlaneAddress := r.Annotations[AllowEmptyControlPlaneAddressAnnotation] == "true" if !allowEmptyControlPlaneAddress && len(r.Spec.ControlPlaneRegions) == 0 { allErrs = append(allErrs, field.Invalid( diff --git a/controllers/hetznerbaremetalremediation_controller_test.go b/controllers/hetznerbaremetalremediation_controller_test.go index fd2aa54fd..633be58bc 100644 --- a/controllers/hetznerbaremetalremediation_controller_test.go +++ b/controllers/hetznerbaremetalremediation_controller_test.go @@ -252,7 +252,7 @@ var _ = Describe("HetznerBareMetalRemediationReconciler", func() { Expect(testEnv.Cleanup(ctx, testNs, hetznerSecret, osSSHSecret, rescueSSHSecret, bootstrapSecret)).To(Succeed()) }) - Context("HetznerBaremetalHost doesn't exist", func() { + Context("HetznerBareMetalHost doesn't exist", func() { AfterEach(func() { Expect(testEnv.Cleanup(ctx, hetznerBareMetalRemediation, hetznerBaremetalMachine)).To(Succeed()) }) @@ -287,7 +287,7 @@ var _ = Describe("HetznerBareMetalRemediationReconciler", func() { }) }) - Context("HetznerBaremetalHost exist", func() { + Context("HetznerBareMetalHost exist", func() { BeforeEach(func() { hostKey = client.ObjectKey{Name: hostName, Namespace: testNs.Name} diff --git a/docs/README.md b/docs/README.md index a76ea2fbd..087cb30e6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,6 +26,7 @@ This is the official documentation of Cluster API Provider Hetzner. Before start - [HetznerBareMetalHost](/docs/caph/03-reference/05-hetzner-bare-metal-host.md) - [HetznerBareMetalMachineTemplate](/docs/caph/03-reference/06-hetzner-bare-metal-machine-template.md) - [HetznerBareMetalRemediationTemplate](/docs/caph/03-reference/07-hetzner-bare-metal-remediation-template.md) +- [Annotations](/docs/caph/03-reference/08-annotations.md) ## Development diff --git a/docs/caph/03-reference/08-annotations.md b/docs/caph/03-reference/08-annotations.md new file mode 100644 index 000000000..f9dd6c3af --- /dev/null +++ b/docs/caph/03-reference/08-annotations.md @@ -0,0 +1,55 @@ +--- + +title: Annotations + +--- + +You can set [Kubernetes Annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) to instruct the Syself CAPH Controller to modify its behavior. + +## Overview of Annotations + +### capi.syself.com/wipe-disk + +| **Resource** | [HetznerBareMetalHost](/docs/caph/03-reference/05-hetzner-bare-metal-host.md) | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Description** | This annotation instructs the Syself CAPH Controller to wipe the disk before provisioning the machine. | +| **Value** | You can use the string `"all"` or a space-separated list of WWNs. For example, `"10:00:00:05:1e:7a:7a:00 eui.00253885910c8cec 0x500a07511bb48b25"`. If the value is empty, no disks will be wiped. The value `"all"` will wipe all disks on the bare-metal machine (not just the one given in the rootDeviceHints). | +| **Auto-Remove** | Enabled: The annotation is removed after the disks are wiped. | + +### capi.syself.com/ignore-check-disk + +| **Resource** | [HetznerBareMetalHost](/docs/caph/03-reference/05-hetzner-bare-metal-host.md) | +| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Description** | This annotation instructs the Syself CAPH Controller to ignore the results of the check-disk step during machine provisioning. The check will be performed, and a Kubernetes Event will be created. However, if this annotation is set, provisioning will continue even if a faulty disk is detected. | +| **Value** | The value is ignored. If the annotation exists, this feature is enabled. | +| **Auto-Remove** | Disabled: The annotation remains on the resource. It is up to the user to remove it. | + +### capi.syself.com/allow-empty-control-plane-address + +| **Resource** | [HetznerCluster](/docs/caph/03-reference/02-hetzner-cluster.md) | +| --------------- | -------------------------------------------------------------------------------------------------------------------------- | +| **Description** | This annotation allows the Syself CAPH Controller to create HetznerCluster resources with an empty `controlPlaneEndpoint`. This is useful to support externally managed control planes ([PR 1106](https://github.com/syself/cluster-api-provider-hetzner/pull/1106)) | +| **Value** | `"true"` enables this feature. All other strings are considered `"false"`. | +| **Auto-Remove** | Disabled: The annotation remains on the resource. | + +### capi.syself.com/constant-bare-metal-hostname + +| **Resource** | Cluster (CRD of Cluster-API), HetznerBareMetalMachine | +| --------------- | ------------------------------------------------------------------------------------------------------------ | +| **Description** | See [Using constant hostnames](/docs/caph/02-topics/05-baremetal/04-constant-hostnames.md) for more details. | +| **Auto-Remove** | Disabled: The annotation remains on the resource. | + +### capi.syself.com/reboot + +| **Resource** | [HetznerBareMetalHost](/docs/caph/03-reference/05-hetzner-bare-metal-host.md) | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Description** | If this annotation is present, the bare-metal machine will be rebooted. This annotation is used by `HetznerBareMetalRemediation` (see [Machine Health Checks with Custom Remediation Template](/docs/caph/02-topics/06-advanced/04-custom-templates-mhc.md)). | +| **Value** | The value is ignored. If the annotation exists, this feature is enabled. | +| **Auto-Remove** | Enabled: The annotation is removed after the reboot. | + +### capi.syself.com/permanent-error + +| **Resource** | [HetznerBareMetalHost](/docs/caph/03-reference/05-hetzner-bare-metal-host.md) | +| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Description** | This annotation is set by the Syself CAPH Controller when a bare-metal machine enters the "permanent error" state. This indicates that human intervention is required (e.g., to fix a broken disk). After the root cause is resolved, the user must remove this annotation to allow the Controller to manage the HetznerBareMetalHost again. | +| **Auto-Remove** | Disabled: The annotation must be removed by the user. |