diff --git a/go.mod b/go.mod index bec2870d8..372fccae4 100644 --- a/go.mod +++ b/go.mod @@ -367,3 +367,5 @@ require ( sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) + +replace github.com/openshift/api => github.com/vr4manta/api v0.0.0-20260121131545-9cd445624861 diff --git a/go.sum b/go.sum index daef2f2bf..e6db6f644 100644 --- a/go.sum +++ b/go.sum @@ -449,8 +449,6 @@ github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jD github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/openshift-eng/openshift-tests-extension v0.0.0-20251105193959-75a0be5d9bd7 h1:Z1swlS6b3Adm6RPhjqefs3DWnNFLDxRX+WC8GMXhja4= github.com/openshift-eng/openshift-tests-extension v0.0.0-20251105193959-75a0be5d9bd7/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M= -github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 h1:kSr3DOlq0NCrHd65HB2o/pBsks7AfRm+fkpf9RLUPoc= -github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY= github.com/openshift/client-go v0.0.0-20251202151200-fb4471581cf8 h1:97rgISdT4IOmXlmEUV5Wr6d8BzzjPclzAjCARLbSlT0= github.com/openshift/client-go v0.0.0-20251202151200-fb4471581cf8/go.mod h1:WVJnsrbSO1J8x8KceOmv1d5CpoN34Uzsaz1O4MIOKJI= github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20250910145856-21d03d30056d h1:+sqUThLi/lmgT5/scmmjnS6+RZFtbdxRAscNfCPyLPI= @@ -616,6 +614,8 @@ github.com/uudashr/iface v1.3.1 h1:bA51vmVx1UIhiIsQFSNq6GZ6VPTk3WNMZgRiCe9R29U= github.com/uudashr/iface v1.3.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg= github.com/vmware/govmomi v0.52.0 h1:JyxQ1IQdllrY7PJbv2am9mRsv3p9xWlIQ66bv+XnyLw= github.com/vmware/govmomi v0.52.0/go.mod h1:Yuc9xjznU3BH0rr6g7MNS1QGvxnJlE1vOvTJ7Lx7dqI= +github.com/vr4manta/api v0.0.0-20260121131545-9cd445624861 h1:CI4EPLfHEssv+uuL1y7feU5zT9Swy0f3PnCE7SbMZYA= +github.com/vr4manta/api v0.0.0-20260121131545-9cd445624861/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= diff --git a/pkg/webhooks/machine_webhook.go b/pkg/webhooks/machine_webhook.go index 38c4fc867..1d6ba2307 100644 --- a/pkg/webhooks/machine_webhook.go +++ b/pkg/webhooks/machine_webhook.go @@ -949,20 +949,15 @@ func processAWSPlacementTenancy(placement machinev1beta1.Placement) field.ErrorL switch *placement.Host.Affinity { 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 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) + if placement.Host.DedicatedHost != nil { + errs = append(errs, validateDedicatedHost(placement.Host.DedicatedHost)...) } case machinev1beta1.HostAffinityDedicatedHost: // We need to make sure DedicatedHost is set with an ID if placement.Host.DedicatedHost == nil { errs = append(errs, field.Required(field.NewPath("spec.placement.host.dedicatedHost"), "dedicatedHost is required when hostAffinity is DedicatedHost, and optional otherwise")) } 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 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 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) - } + errs = append(errs, validateDedicatedHost(placement.Host.DedicatedHost)...) } default: errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.affinity"), placement.Host.Affinity, "hostAffinity must be either AnyAvailable or DedicatedHost")) @@ -983,6 +978,54 @@ func processAWSPlacementTenancy(placement machinev1beta1.Placement) field.ErrorL return errs } +// validateDedicatedHost validates that all fields in the DedicatedHost are configured correctly. +func validateDedicatedHost(host *machinev1beta1.DedicatedHost) field.ErrorList { + var errs field.ErrorList + + // If host is nil, then nothing to validate + if host == nil { + return errs + } + + strategy := machinev1beta1.AllocationStrategyUserProvided + if host.AllocationStrategy != nil { + strategy = *host.AllocationStrategy + } + + switch strategy { + // Empty string is for backward compatability in case an existing config exists with the allocation strategy not set. + // Default is User Provided. + case machinev1beta1.AllocationStrategyUserProvided, "": + // User Provided requires the ID being set of the host to use + if host.ID == "" { + errs = append(errs, field.Required(field.NewPath("spec.placement.host.dedicatedHost.id"), "id is required when allocationStrategy is UserProvided and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) + } else if !awsDedicatedHostNamePattern.MatchString(host.ID) { + errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.id"), host.ID, "id must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)")) + } + + // DynamicHostAllocation is not allowed if user provided + if host.DynamicHostAllocation != nil { + errs = append(errs, field.Invalid(field.NewPath("spec.placement.host.dedicatedHost.dynamicHostAllocation"), host.ID, "dynamicHostAllocation is only allowed when allocationStrategy is Dynamic")) + } + case machinev1beta1.AllocationStrategyDynamic: + // ID must not be set + if host.ID != "" { + errs = append(errs, field.Forbidden(field.NewPath("spec.placement.host.dedicatedHost.id"), "id is only allowed when allocationStrategy is Provided")) + } + default: + errs = append( + errs, + field.Invalid( + field.NewPath("spec.placement.host.dedicatedHost.allocationStrategy"), + host.AllocationStrategy, + fmt.Sprintf("Invalid allocationStrategy, the only allowed options are: %s, %s", machinev1beta1.AllocationStrategyUserProvided, machinev1beta1.AllocationStrategyDynamic), + ), + ) + } + + return errs +} + // getDuplicatedTags iterates through the AWS TagSpecifications // to determine if any tag Name is duplicated within the list. // A list of duplicated names will be returned. diff --git a/pkg/webhooks/machine_webhook_test.go b/pkg/webhooks/machine_webhook_test.go index 087e90b62..0b5d210e2 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 8 or 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 when allocationStrategy is UserProvided 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 8 or 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 when allocationStrategy is UserProvided 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", @@ -532,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 8 or 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 when allocationStrategy is UserProvided 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", @@ -551,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 8 or 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 when allocationStrategy is UserProvided 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", @@ -679,6 +679,206 @@ func TestMachineCreation(t *testing.T) { }, expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host: Forbidden: host may only be specified when tenancy is 'host'", }, + { + name: "configure AllocationStrategy Provided with valid 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyUserProvided), + ID: "h-1234567890abcdef0", + }, + }, + }, + }, + }, + expectedError: "", + }, + { + name: "configure AllocationStrategy Provided without 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyUserProvided), + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required when allocationStrategy is UserProvided and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, + { + name: "configure AllocationStrategy UserProvided with empty 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyUserProvided), + ID: "", + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required when allocationStrategy is UserProvided and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, + { + name: "configure AllocationStrategy UserProvided with DynamicHostAllocation", + 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyUserProvided), + ID: "h-1234567890abcdef0", + DynamicHostAllocation: &machinev1beta1.DynamicHostAllocationSpec{ + Tags: map[string]string{"key": "value"}, + }, + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.dynamicHostAllocation: Invalid value: \"h-1234567890abcdef0\": dynamicHostAllocation is only allowed when allocationStrategy is Dynamic", + }, + { + name: "configure AllocationStrategy Dynamic without 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyDynamic), + }, + }, + }, + }, + }, + expectedError: "", + }, + { + name: "configure AllocationStrategy Dynamic with DynamicHostAllocation", + 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyDynamic), + DynamicHostAllocation: &machinev1beta1.DynamicHostAllocationSpec{ + Tags: map[string]string{"env": "test"}, + }, + }, + }, + }, + }, + }, + expectedError: "", + }, + { + name: "configure AllocationStrategy Dynamic with 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{ + AllocationStrategy: ptr.To(machinev1beta1.AllocationStrategyDynamic), + ID: "h-1234567890abcdef0", + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Forbidden: id is only allowed when allocationStrategy is Provided", + }, + { + name: "configure nil AllocationStrategy with valid ID (backward compatibility)", + 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{ + AllocationStrategy: nil, + ID: "h-1234567890abcdef0", + }, + }, + }, + }, + }, + expectedError: "", + }, + { + name: "configure nil AllocationStrategy without ID (backward compatibility)", + 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{ + AllocationStrategy: nil, + }, + }, + }, + }, + }, + expectedError: "admission webhook \"validation.machine.machine.openshift.io\" denied the request: spec.placement.host.dedicatedHost.id: Required value: id is required when allocationStrategy is UserProvided and must start with 'h-' followed by 8 or 17 lowercase hexadecimal characters (0-9 and a-f)", + }, { name: "with VolumeType set to gp3 and Throughput set under minium value", platformType: osconfigv1.AWSPlatformType, diff --git a/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go b/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go index d1d5941fa..133d5b019 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go @@ -454,21 +454,71 @@ type HostAffinity string const ( // HostAffinityAnyAvailable lets the platform select any available dedicated host. + HostAffinityAnyAvailable HostAffinity = "AnyAvailable" // HostAffinityDedicatedHost requires specifying a particular host via dedicatedHost.host.hostID. HostAffinityDedicatedHost HostAffinity = "DedicatedHost" ) +// AllocationStrategy selects how a dedicated host is provided to the system for assigning to the instance. +// +kubebuilder:validation:Enum:=UserProvided;Dynamic +type AllocationStrategy string + +const ( + // AllocationStrategyUserProvided specifies that the system should assign instances to a user-provided dedicated host. + AllocationStrategyUserProvided AllocationStrategy = "UserProvided" + + // AllocationStrategyDynamic specifies that the system should dynamically allocate a dedicated host for instances. + AllocationStrategyDynamic AllocationStrategy = "Dynamic" +) + // DedicatedHost represents the configuration for the usage of dedicated host. +// +kubebuilder:validation:XValidation:rule="self.allocationStrategy == 'UserProvided' ? has(self.id) : true",message="id is required when allocationStrategy is UserProvided" +// +kubebuilder:validation:XValidation:rule="has(self.id) ? self.allocationStrategy == 'UserProvided' : true",message="id is only allowed when allocationStrategy is UserProvided" +// +kubebuilder:validation:XValidation:rule="has(self.dynamicHostAllocation) ? self.allocationStrategy == 'Dynamic' : true",message="dynamicHostAllocation is only allowed when allocationStrategy is Dynamic" +// +union type DedicatedHost struct { + // allocationStrategy specifies if the dedicated host will be provided by the admin through the id field or if the host will be dynamically allocated. + // Valid values are UserProvided and Dynamic. + // This field is optional and defaults to "UserProvided". + // When AllocationStrategy is set to UserProvided, an ID of the dedicated host to assign must be provided. + // When AllocationStrategy is set to Dynamic, a dedicated host will be allocated and used to assign instances. + // When AllocationStrategy is set to Dynamic, and DynamicHostAllocation is configured, a dedicated host will be allocated and the tags in DynamicHostAllocation will be assigned to that host. + // +optional + // +unionDiscriminator + // +default="UserProvided" + AllocationStrategy *AllocationStrategy `json:"allocationStrategy,omitempty"` + // id identifies the AWS Dedicated Host on which the instance must run. // The value must start with "h-" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). // The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. // Must be either 10 or 19 characters in length. + // This field is required when allocationStrategy is UserProvided, and forbidden when allocationStrategy is Dynamic. + // When omitted, allocationStrategy must be set to Dynamic to enable automatic host allocation. // +kubebuilder:validation:XValidation:rule="self.matches('^h-([0-9a-f]{8}|[0-9a-f]{17})$')",message="hostID must start with 'h-' followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f)" // +kubebuilder:validation:MinLength=10 // +kubebuilder:validation:MaxLength=19 - // +required + // +optional + // +unionMember=UserProvided ID string `json:"id,omitempty"` + + // dynamicHostAllocation specifies tags to apply to a dynamically allocated dedicated host. + // This field is only allowed when allocationStrategy is Dynamic, and is mutually exclusive with id. + // When specified, a dedicated host will be allocated with the provided tags applied. + // When omitted (and allocationStrategy is Dynamic), a dedicated host will be allocated without any additional tags. + // +optional + // +unionMember=Dynamic + DynamicHostAllocation *DynamicHostAllocationSpec `json:"dynamicHostAllocation,omitempty"` +} + +// DynamicHostAllocationSpec defines the configuration for dynamic dedicated host allocation. +// This specification always allocates exactly one dedicated host per machine. +// +kubebuilder:validation:MinProperties=1 +type DynamicHostAllocationSpec struct { + // tags specifies a set of key-value pairs to apply to the allocated dedicated host. + // When omitted, no additional user-defined tags will be applied to the allocated host. + // +kubebuilder:validation:MinProperties=1 + // +optional + Tags map[string]string `json:"tags,omitempty"` } diff --git a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go index d08906c7d..9e1a027d2 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go @@ -512,6 +512,16 @@ func (in *DataDiskManagedDiskParameters) DeepCopy() *DataDiskManagedDiskParamete // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DedicatedHost) DeepCopyInto(out *DedicatedHost) { *out = *in + if in.AllocationStrategy != nil { + in, out := &in.AllocationStrategy, &out.AllocationStrategy + *out = new(AllocationStrategy) + **out = **in + } + if in.DynamicHostAllocation != nil { + in, out := &in.DynamicHostAllocation, &out.DynamicHostAllocation + *out = new(DynamicHostAllocationSpec) + (*in).DeepCopyInto(*out) + } return } @@ -557,6 +567,29 @@ func (in *DiskSettings) DeepCopy() *DiskSettings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DynamicHostAllocationSpec) DeepCopyInto(out *DynamicHostAllocationSpec) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicHostAllocationSpec. +func (in *DynamicHostAllocationSpec) DeepCopy() *DynamicHostAllocationSpec { + if in == nil { + return nil + } + out := new(DynamicHostAllocationSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EBSBlockDeviceSpec) DeepCopyInto(out *EBSBlockDeviceSpec) { *out = *in @@ -935,7 +968,7 @@ func (in *HostPlacement) DeepCopyInto(out *HostPlacement) { if in.DedicatedHost != nil { in, out := &in.DedicatedHost, &out.DedicatedHost *out = new(DedicatedHost) - **out = **in + (*in).DeepCopyInto(*out) } return } diff --git a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go index 093a40076..6f348e971 100644 --- a/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go @@ -93,14 +93,25 @@ func (CPUOptions) SwaggerDoc() map[string]string { } var map_DedicatedHost = map[string]string{ - "": "DedicatedHost represents the configuration for the usage of dedicated host.", - "id": "id identifies the AWS Dedicated Host on which the instance must run. The value must start with \"h-\" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. Must be either 10 or 19 characters in length.", + "": "DedicatedHost represents the configuration for the usage of dedicated host.", + "allocationStrategy": "allocationStrategy specifies if the dedicated host will be provided by the admin through the id field or if the host will be dynamically allocated. Valid values are UserProvided and Dynamic. This field is optional and defaults to \"UserProvided\". When AllocationStrategy is set to UserProvided, an ID of the dedicated host to assign must be provided. When AllocationStrategy is set to Dynamic, a dedicated host will be allocated and used to assign instances. When AllocationStrategy is set to Dynamic, and DynamicHostAllocation is configured, a dedicated host will be allocated and the tags in DynamicHostAllocation will be assigned to that host.", + "id": "id identifies the AWS Dedicated Host on which the instance must run. The value must start with \"h-\" followed by either 8 or 17 lowercase hexadecimal characters (0-9 and a-f). The use of 8 lowercase hexadecimal characters is for older legacy hosts that may not have been migrated to newer format. Must be either 10 or 19 characters in length. This field is required when allocationStrategy is UserProvided, and forbidden when allocationStrategy is Dynamic. When omitted, allocationStrategy must be set to Dynamic to enable automatic host allocation.", + "dynamicHostAllocation": "dynamicHostAllocation specifies tags to apply to a dynamically allocated dedicated host. This field is only allowed when allocationStrategy is Dynamic, and is mutually exclusive with id. When specified, a dedicated host will be allocated with the provided tags applied. When omitted (and allocationStrategy is Dynamic), a dedicated host will be allocated without any additional tags.", } func (DedicatedHost) SwaggerDoc() map[string]string { return map_DedicatedHost } +var map_DynamicHostAllocationSpec = map[string]string{ + "": "DynamicHostAllocationSpec defines the configuration for dynamic dedicated host allocation. This specification always allocates exactly one dedicated host per machine.", + "tags": "tags specifies a set of key-value pairs to apply to the allocated dedicated host. When omitted, no additional user-defined tags will be applied to the allocated host.", +} + +func (DynamicHostAllocationSpec) SwaggerDoc() map[string]string { + return map_DynamicHostAllocationSpec +} + var map_EBSBlockDeviceSpec = map[string]string{ "": "EBSBlockDeviceSpec describes a block device for an EBS volume. https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/EbsBlockDevice", "deleteOnTermination": "Indicates whether the EBS volume is deleted on machine termination.\n\nDeprecated: setting this field has no effect.", diff --git a/vendor/modules.txt b/vendor/modules.txt index 3eb1d928a..9a7896a9a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -976,7 +976,7 @@ github.com/openshift-eng/openshift-tests-extension/pkg/ginkgo github.com/openshift-eng/openshift-tests-extension/pkg/junit github.com/openshift-eng/openshift-tests-extension/pkg/util/sets github.com/openshift-eng/openshift-tests-extension/pkg/version -# github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 +# github.com/openshift/api v0.0.0-20260114133223-6ab113cb7368 => github.com/vr4manta/api v0.0.0-20260121131545-9cd445624861 ## explicit; go 1.24.0 github.com/openshift/api github.com/openshift/api/annotations @@ -3668,3 +3668,4 @@ sigs.k8s.io/yaml/kyaml # k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20251015171918-61114aa5a292 # k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20251015171918-61114aa5a292 # k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20251027205255-4e0347881cbd +# github.com/openshift/api => github.com/vr4manta/api v0.0.0-20260121131545-9cd445624861