From 0313a6916739fb40a8a8b9ff828869a5d90e081c Mon Sep 17 00:00:00 2001 From: vr4manta Date: Thu, 8 Jan 2026 13:51:10 -0500 Subject: [PATCH] Updated AWS dedicated host id validation pattern --- pkg/webhooks/machine_webhook.go | 8 +- pkg/webhooks/machine_webhook_test.go | 121 +++++++++++++++++++++++++-- 2 files changed, 119 insertions(+), 10 deletions(-) diff --git a/pkg/webhooks/machine_webhook.go b/pkg/webhooks/machine_webhook.go index d0cee80f1..38c4fc867 100644 --- a/pkg/webhooks/machine_webhook.go +++ b/pkg/webhooks/machine_webhook.go @@ -53,7 +53,7 @@ var ( // AWS Variables / Defaults // awsDedicatedHostNamePattern is used to validate the id of a dedicated host - awsDedicatedHostNamePattern = regexp.MustCompile(`^h-[0-9a-f]{17}$`) + awsDedicatedHostNamePattern = regexp.MustCompile(`^h-([0-9a-f]{8}|[0-9a-f]{17})$`) // Azure Defaults defaultAzureVnet = func(clusterID string) string { @@ -950,7 +950,7 @@ func processAWSPlacementTenancy(placement machinev1beta1.Placement) field.ErrorL case machinev1beta1.HostAffinityAnyAvailable: // DedicatedHost is optional. If it is set, make sure it follows conventions if placement.Host.DedicatedHost != nil && !awsDedicatedHostNamePattern.MatchString(placement.Host.DedicatedHost.ID) { - errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.id"), placement.Host.DedicatedHost.ID, "id must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)")) + errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.id"), placement.Host.DedicatedHost.ID, "id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) } case machinev1beta1.HostAffinityDedicatedHost: // We need to make sure DedicatedHost is set with an ID @@ -959,9 +959,9 @@ func processAWSPlacementTenancy(placement machinev1beta1.Placement) field.ErrorL } else { // If not set, return required error. If it does not match pattern, return pattern failure message. if placement.Host.DedicatedHost.ID == "" { - errs = append(errs, field.Required(field.NewPath("spec.placement.host.dedicatedHost.id"), "id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)")) + errs = append(errs, field.Required(field.NewPath("spec.placement.host.dedicatedHost.id"), "id is required and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) } else if !awsDedicatedHostNamePattern.MatchString(placement.Host.DedicatedHost.ID) { - errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.id"), placement.Host.DedicatedHost.ID, "id must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)")) + errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.id"), placement.Host.DedicatedHost.ID, "id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) } } default: diff --git a/pkg/webhooks/machine_webhook_test.go b/pkg/webhooks/machine_webhook_test.go index 498f5a012..087e90b62 100644 --- a/pkg/webhooks/machine_webhook_test.go +++ b/pkg/webhooks/machine_webhook_test.go @@ -376,7 +376,7 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure host placement with AnyAvailable affinity and empty ID", @@ -399,7 +399,7 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure host placement with AnyAvailable affinity and invalid ID", @@ -422,7 +422,7 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"invalid\": id must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"invalid\": id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure host placement with invalid affinity", @@ -467,6 +467,52 @@ func TestMachineCreation(t *testing.T) { }, expectedError: "", }, + { + name: "configure host placement with DedicatedHost affinity and valid 8-character ID", + platformType: osconfigv1.AWSPlatformType, + clusterID: "aws-cluster", + providerSpecValue: &kruntime.RawExtension{ + Object: &machinev1beta1.AWSMachineProviderConfig{ + AMI: machinev1beta1.AWSResourceReference{ + ID: ptr.To[string]("ami"), + }, + InstanceType: "test", + Placement: machinev1beta1.Placement{ + Tenancy: machinev1beta1.HostTenancy, + Host: &machinev1beta1.HostPlacement{ + Affinity: ptr.To(machinev1beta1.HostAffinityDedicatedHost), + DedicatedHost: &machinev1beta1.DedicatedHost{ + ID: "h-12345678", + }, + }, + }, + }, + }, + expectedError: "", + }, + { + name: "configure host placement with AnyAvailable affinity and valid 8-character ID", + platformType: osconfigv1.AWSPlatformType, + clusterID: "aws-cluster", + providerSpecValue: &kruntime.RawExtension{ + Object: &machinev1beta1.AWSMachineProviderConfig{ + AMI: machinev1beta1.AWSResourceReference{ + ID: ptr.To[string]("ami"), + }, + InstanceType: "test", + Placement: machinev1beta1.Placement{ + Tenancy: machinev1beta1.HostTenancy, + Host: &machinev1beta1.HostPlacement{ + Affinity: ptr.To(machinev1beta1.HostAffinityAnyAvailable), + DedicatedHost: &machinev1beta1.DedicatedHost{ + ID: "h-12345678", + }, + }, + }, + }, + }, + expectedError: "", + }, { name: "configure host placement with DedicatedHost affinity and empty ID", platformType: osconfigv1.AWSPlatformType, @@ -486,7 +532,7 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure host placement with DedicatedHost affinity and ID not set", @@ -505,7 +551,7 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure host placement with DedicatedHost affinity and invalid ID", @@ -526,7 +572,70 @@ func TestMachineCreation(t *testing.T) { }, }, }, - expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"invalid\": id must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)", + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"invalid\": id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, + { + name: "configure host placement with DedicatedHost affinity and 9-character ID (invalid length)", + platformType: osconfigv1.AWSPlatformType, + clusterID: "aws-cluster", + providerSpecValue: &kruntime.RawExtension{ + Object: &machinev1beta1.AWSMachineProviderConfig{ + AMI: machinev1beta1.AWSResourceReference{ID: ptr.To[string]("ami")}, + InstanceType: "test", + Placement: machinev1beta1.Placement{ + Tenancy: machinev1beta1.HostTenancy, + Host: &machinev1beta1.HostPlacement{ + Affinity: ptr.To(machinev1beta1.HostAffinityDedicatedHost), + DedicatedHost: &machinev1beta1.DedicatedHost{ + ID: "h-123456789", + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"h-123456789\": id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, + { + name: "configure host placement with DedicatedHost affinity and 16-character ID (invalid length)", + platformType: osconfigv1.AWSPlatformType, + clusterID: "aws-cluster", + providerSpecValue: &kruntime.RawExtension{ + Object: &machinev1beta1.AWSMachineProviderConfig{ + AMI: machinev1beta1.AWSResourceReference{ID: ptr.To[string]("ami")}, + InstanceType: "test", + Placement: machinev1beta1.Placement{ + Tenancy: machinev1beta1.HostTenancy, + Host: &machinev1beta1.HostPlacement{ + Affinity: ptr.To(machinev1beta1.HostAffinityDedicatedHost), + DedicatedHost: &machinev1beta1.DedicatedHost{ + ID: "h-1234567890abcdef", + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"h-1234567890abcdef\": id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, + { + name: "configure host placement with DedicatedHost affinity and 8-character ID with uppercase (invalid)", + platformType: osconfigv1.AWSPlatformType, + clusterID: "aws-cluster", + providerSpecValue: &kruntime.RawExtension{ + Object: &machinev1beta1.AWSMachineProviderConfig{ + AMI: machinev1beta1.AWSResourceReference{ID: ptr.To[string]("ami")}, + InstanceType: "test", + Placement: machinev1beta1.Placement{ + Tenancy: machinev1beta1.HostTenancy, + Host: &machinev1beta1.HostPlacement{ + Affinity: ptr.To(machinev1beta1.HostAffinityDedicatedHost), + DedicatedHost: &machinev1beta1.DedicatedHost{ + ID: "h-1234ABCD", + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Invalid value: \"h-1234ABCD\": id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", }, { name: "configure dedicated tenancy with host placement",