Skip to content

Commit f5cae1f

Browse files
Merge pull request #1419 from vr4manta/SPLAT-2167
SPLAT-2167: Added dedicated hosts support for AWS
2 parents c8772d3 + 9ebb6da commit f5cae1f

File tree

912 files changed

+577
-217485
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

912 files changed

+577
-217485
lines changed

cmd/machine-api-tests-ext/provider.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"context"
54
"encoding/json"
65
"fmt"
76
"os"
@@ -10,10 +9,7 @@ import (
109

1110
"github.com/onsi/ginkgo/v2"
1211
"github.com/onsi/gomega"
13-
corev1 "k8s.io/api/core/v1"
14-
kclientset "k8s.io/client-go/kubernetes"
1512
"k8s.io/client-go/tools/clientcmd"
16-
"k8s.io/kubernetes/openshift-hack/e2e"
1713
conformancetestdata "k8s.io/kubernetes/test/conformance/testdata"
1814
"k8s.io/kubernetes/test/e2e/framework"
1915
"k8s.io/kubernetes/test/e2e/framework/testfiles"
@@ -90,11 +86,6 @@ func initializeTestFramework(provider string) error {
9086
}
9187
testContext.Host = cfg.Host
9288

93-
// Ensure that Kube tests run privileged (like they do upstream)
94-
testContext.CreateTestingNS = func(ctx context.Context, baseName string, c kclientset.Interface, labels map[string]string) (*corev1.Namespace, error) {
95-
return e2e.CreateTestingNS(ctx, baseName, c, labels, true)
96-
}
97-
9889
gomega.RegisterFailHandler(ginkgo.Fail)
9990

10091
framework.AfterReadingAllFlags(testContext)

go.mod

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ go 1.24.0
66
// an API yet we can leverage so that I do not have to copy what openshift/kubernetes/openshift-hack/cmd/k8s-tests-ext did to initialize.
77
replace (
88
github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1
9-
k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20251015171918-61114aa5a292 // openshift kubernetes has very old copy of k8s.io/kubernetes/pkg/kubelet/server/server.go
10-
k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20251015171918-61114aa5a292 // openshift kubernetes has very old copy of k8s.io/kubernetes/cmd/kubelet/app/options/options.go
11-
k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20251027205255-4e0347881cbd
9+
// I was able to remove the following by removing the namespace checking logic of OTE. Current assumption is origin is making sure all permissions are set before launching OTE.
10+
//k8s.io/apiserver => github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20250716113245-b94367cabf3e // openshift kubernetes has very old copy of k8s.io/kubernetes/pkg/kubelet/server/server.go
11+
//k8s.io/kubelet => github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20250716113245-b94367cabf3e // openshift kubernetes has very old copy of k8s.io/kubernetes/cmd/kubelet/app/options/options.go:
12+
//k8s.io/kubernetes => github.com/openshift/kubernetes v1.30.1-0.20250716113245-b94367cabf3e //v1.30.1-0.20250704150419-38c60a516ecb
1213
)
1314

1415
require (
@@ -19,7 +20,7 @@ require (
1920
github.com/onsi/ginkgo/v2 v2.27.2
2021
github.com/onsi/gomega v1.38.2
2122
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251105193959-75a0be5d9bd7
22-
github.com/openshift/api v0.0.0-20251106190826-ebe535b08719
23+
github.com/openshift/api v0.0.0-20251111193948-50e2ece149d7
2324
github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235
2425
github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20250910145856-21d03d30056d
2526
github.com/openshift/cluster-control-plane-machine-set-operator v0.0.0-20251029084908-344babe6a957
@@ -127,7 +128,6 @@ require (
127128
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
128129
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
129130
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
130-
github.com/fatih/camelcase v1.0.0 // indirect
131131
github.com/fatih/color v1.18.0 // indirect
132132
github.com/fatih/structtag v1.2.0 // indirect
133133
github.com/felixge/httpsnoop v1.0.4 // indirect
@@ -237,10 +237,9 @@ require (
237237
github.com/nishanths/predeclared v0.2.2 // indirect
238238
github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
239239
github.com/olekukonko/tablewriter v0.0.5 // indirect
240-
github.com/opencontainers/cgroups v0.0.3 // indirect
240+
github.com/opencontainers/cgroups v0.0.1 // indirect
241241
github.com/opencontainers/go-digest v1.0.0 // indirect
242242
github.com/opencontainers/image-spec v1.1.1 // indirect
243-
github.com/opencontainers/runc v1.2.5 // indirect
244243
github.com/opencontainers/runtime-spec v1.2.0 // indirect
245244
github.com/opencontainers/selinux v1.11.1 // indirect
246245
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
@@ -315,7 +314,6 @@ require (
315314
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
316315
go.opentelemetry.io/otel/trace v1.35.0 // indirect
317316
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
318-
go.uber.org/atomic v1.11.0 // indirect
319317
go.uber.org/automaxprocs v1.6.0 // indirect
320318
go.uber.org/multierr v1.11.0 // indirect
321319
go.uber.org/zap v1.27.0 // indirect
@@ -339,7 +337,6 @@ require (
339337
google.golang.org/grpc v1.72.1 // indirect
340338
google.golang.org/protobuf v1.36.8 // indirect
341339
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
342-
gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect
343340
gopkg.in/inf.v0 v0.9.1 // indirect
344341
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
345342
gopkg.in/warnings.v0 v0.1.2 // indirect
@@ -349,7 +346,6 @@ require (
349346
k8s.io/apiextensions-apiserver v0.34.1 // indirect
350347
k8s.io/cli-runtime v0.34.1 // indirect
351348
k8s.io/cloud-provider v0.32.0 // indirect
352-
k8s.io/cluster-bootstrap v0.32.3 // indirect
353349
k8s.io/component-helpers v0.34.1 // indirect
354350
k8s.io/controller-manager v0.32.1 // indirect
355351
k8s.io/cri-api v0.34.1 // indirect

go.sum

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -435,34 +435,26 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
435435
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
436436
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
437437
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
438-
github.com/opencontainers/cgroups v0.0.3 h1:Jc9dWh/0YLGjdy6J/9Ln8NM5BfTA4W2BY0GMozy3aDU=
439-
github.com/opencontainers/cgroups v0.0.3/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs=
438+
github.com/opencontainers/cgroups v0.0.1 h1:MXjMkkFpKv6kpuirUa4USFBas573sSAY082B4CiHEVA=
439+
github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs=
440440
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
441441
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
442442
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
443443
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
444-
github.com/opencontainers/runc v1.2.5 h1:8KAkq3Wrem8bApgOHyhRI/8IeLXIfmZ6Qaw6DNSLnA4=
445-
github.com/opencontainers/runc v1.2.5/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=
446444
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
447445
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
448446
github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
449447
github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
450448
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251105193959-75a0be5d9bd7 h1:Z1swlS6b3Adm6RPhjqefs3DWnNFLDxRX+WC8GMXhja4=
451449
github.com/openshift-eng/openshift-tests-extension v0.0.0-20251105193959-75a0be5d9bd7/go.mod h1:6gkP5f2HL0meusT0Aim8icAspcD1cG055xxBZ9yC68M=
452-
github.com/openshift/api v0.0.0-20251106190826-ebe535b08719 h1:KEwYyKaJniwhoyLB75tAMmJn9pMlk0PUlRfrsXYOhwM=
453-
github.com/openshift/api v0.0.0-20251106190826-ebe535b08719/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
450+
github.com/openshift/api v0.0.0-20251111193948-50e2ece149d7 h1:MemawsK6SpxEaE5y0NqO5sIX3yTLIIyP89w6DGKukAk=
451+
github.com/openshift/api v0.0.0-20251111193948-50e2ece149d7/go.mod h1:d5uzF0YN2nQQFA0jIEWzzOZ+edmo6wzlGLvx5Fhz4uY=
454452
github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235 h1:9JBeIXmnHlpXTQPi7LPmu1jdxznBhAE7bb1K+3D8gxY=
455453
github.com/openshift/client-go v0.0.0-20251015124057-db0dee36e235/go.mod h1:L49W6pfrZkfOE5iC1PqEkuLkXG4W0BX4w8b+L2Bv7fM=
456454
github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20250910145856-21d03d30056d h1:+sqUThLi/lmgT5/scmmjnS6+RZFtbdxRAscNfCPyLPI=
457455
github.com/openshift/cluster-api-actuator-pkg/testutils v0.0.0-20250910145856-21d03d30056d/go.mod h1:9+FWWWLkVrnBo1eYhA/0Ehlq5JMgIAHtcB0IF+qV1AA=
458456
github.com/openshift/cluster-control-plane-machine-set-operator v0.0.0-20251029084908-344babe6a957 h1:eVnkMTFnirnoUOlAUT3Hy8WriIi1JoSrilWym3Dl8Q4=
459457
github.com/openshift/cluster-control-plane-machine-set-operator v0.0.0-20251029084908-344babe6a957/go.mod h1:TBlORAAtNZ/Tl86pO7GjNXKsH/g0QAW5GnvYstdOhYI=
460-
github.com/openshift/kubernetes v1.30.1-0.20251027205255-4e0347881cbd h1:WCCP41uY1QoqrDeykXFF/Dmf8NV3fnnAXUnh1oVFxW8=
461-
github.com/openshift/kubernetes v1.30.1-0.20251027205255-4e0347881cbd/go.mod h1:w3+IfrXNp5RosdDXg3LB55yijJqR/FwouvVntYHQf0o=
462-
github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20251015171918-61114aa5a292 h1:Uq4CTGAl32NYNK7KD35oRg7pdZOFkUF+/2wGSyR0VYA=
463-
github.com/openshift/kubernetes/staging/src/k8s.io/apiserver v0.0.0-20251015171918-61114aa5a292/go.mod h1:TRSSqgXggJaDK5vtVtlQ9wEYOk32Pl+9tf0ROf3ljiM=
464-
github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20251015171918-61114aa5a292 h1:ITqtj/xBNlSPChpvV4a+VQ93Sk5RFkwRx+CnIWBrZ98=
465-
github.com/openshift/kubernetes/staging/src/k8s.io/kubelet v0.0.0-20251015171918-61114aa5a292/go.mod h1:+bTwPbT5dZB8j6eKQHBZRMfNmY6MEryba1wQljr9VWw=
466458
github.com/openshift/library-go v0.0.0-20251107090138-0de9712313a5 h1:Gq8jCFgSrilZ2ZHjQleFZWlblikc1aaRZ0hqs+yvrP4=
467459
github.com/openshift/library-go v0.0.0-20251107090138-0de9712313a5/go.mod h1:OlFFws1AO51uzfc48MsStGE4SFMWlMZD0+f5a/zCtKI=
468460
github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ=
@@ -685,8 +677,6 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
685677
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
686678
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
687679
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
688-
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
689-
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
690680
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
691681
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
692682
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -873,6 +863,8 @@ k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJb
873863
k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
874864
k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
875865
k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
866+
k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA=
867+
k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0=
876868
k8s.io/cli-runtime v0.34.1 h1:btlgAgTrYd4sk8vJTRG6zVtqBKt9ZMDeQZo2PIzbL7M=
877869
k8s.io/cli-runtime v0.34.1/go.mod h1:aVA65c+f0MZiMUPbseU/M9l1Wo2byeaGwUuQEQVVveE=
878870
k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
@@ -909,6 +901,10 @@ k8s.io/kube-scheduler v0.34.1 h1:S5td6VZwC3lCqERXclerDXhJ26zYc6JroY0s03+PqJ8=
909901
k8s.io/kube-scheduler v0.34.1/go.mod h1:UiOkod/w+HKoGut9mz9ie4s4KcI82vmLFdq1iIgsmRs=
910902
k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI=
911903
k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A=
904+
k8s.io/kubelet v0.34.1 h1:doAaTA9/Yfzbdq/u/LveZeONp96CwX9giW6b+oHn4m4=
905+
k8s.io/kubelet v0.34.1/go.mod h1:PtV3Ese8iOM19gSooFoQT9iyRisbmJdAPuDImuccbbA=
906+
k8s.io/kubernetes v1.34.1 h1:F3p8dtpv+i8zQoebZeK5zBqM1g9x1aIdnA5vthvcuUk=
907+
k8s.io/kubernetes v1.34.1/go.mod h1:iu+FhII+Oc/1gGWLJcer6wpyih441aNFHl7Pvm8yPto=
912908
k8s.io/mount-utils v0.34.1 h1:zMBEFav8Rxwm54S8srzy5FxAc4KQ3X4ZcjnqTCzHmZk=
913909
k8s.io/mount-utils v0.34.1/go.mod h1:MIjjYlqJ0ziYQg0MO09kc9S96GIcMkhF/ay9MncF0GA=
914910
k8s.io/pod-security-admission v0.32.2 h1:zDfAb/t0LbNU3z0ZMHtCb1zp8x05gWCGhmBYpUptm9A=

pkg/operator/operator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ func (optr *Operator) maoConfigFromInfrastructure() (*OperatorConfig, error) {
472472
// flags, we selectively populate the map (and therefore passed
473473
// as args)
474474
features := map[string]bool{
475+
string(apifeatures.FeatureGateAWSDedicatedHosts): featureGates.Enabled(apifeatures.FeatureGateAWSDedicatedHosts),
475476
string(apifeatures.FeatureGateMachineAPIMigration): featureGates.Enabled(apifeatures.FeatureGateMachineAPIMigration),
476477
string(apifeatures.FeatureGateAzureWorkloadIdentity): featureGates.Enabled(apifeatures.FeatureGateAzureWorkloadIdentity),
477478
string(apifeatures.FeatureGateVSphereMultiDisk): featureGates.Enabled(apifeatures.FeatureGateVSphereMultiDisk),

pkg/operator/operator_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ var (
4545
{Name: apifeatures.FeatureGateAzureWorkloadIdentity},
4646
{Name: apifeatures.FeatureGateVSphereMultiDisk},
4747
{Name: apifeatures.FeatureGateVSphereHostVMGroupZonal},
48+
{Name: apifeatures.FeatureGateAWSDedicatedHosts},
4849
}
4950

5051
enabledFeatureMap = map[string]bool{
5152
"MachineAPIMigration": true,
5253
"AzureWorkloadIdentity": true,
5354
"VSphereMultiDisk": true,
5455
"VSphereHostVMGroupZonal": true,
56+
"AWSDedicatedHosts": true,
5557
}
5658
)
5759

pkg/webhooks/machine_webhook.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ type systemSpecifications struct {
5050
type machineArch string
5151

5252
var (
53+
// AWS Variables / Defaults
54+
55+
// awsDedicatedHostNamePattern is used to validate the id of a dedicated host
56+
awsDedicatedHostNamePattern = regexp.MustCompile(`^h-[0-9a-f]{17}$`)
57+
5358
// Azure Defaults
5459
defaultAzureVnet = func(clusterID string) string {
5560
return fmt.Sprintf("%s-vnet", clusterID)
@@ -897,6 +902,38 @@ func validateAWS(m *machinev1beta1.Machine, config *admissionConfig) (bool, []st
897902
}
898903
}
899904

905+
// Dedicated host support.
906+
// Check if host placement is configured. If so, then we need to determine placement affinity and validate configs.
907+
if providerSpec.HostPlacement != nil {
908+
klog.V(4).Infof("Validating AWS Host Placement")
909+
placement := *providerSpec.HostPlacement
910+
if placement.Affinity == nil {
911+
errs = append(errs, field.Required(field.NewPath("spec.hostPlacement.affinity"), "affinity is required and must be set to either AnyAvailable or DedicatedHost"))
912+
} else {
913+
switch *placement.Affinity {
914+
case machinev1beta1.HostAffinityAnyAvailable:
915+
// Cannot have DedicatedHost set
916+
if placement.DedicatedHost != nil {
917+
errs = append(errs, field.Forbidden(field.NewPath("spec.hostPlacement.dedicatedHost"), "dedicatedHost is required when affinity is DedicatedHost, and forbidden otherwise"))
918+
}
919+
case machinev1beta1.HostAffinityDedicatedHost:
920+
// We need to make sure DedicatedHost is set with a HostID
921+
if placement.DedicatedHost == nil {
922+
errs = append(errs, field.Required(field.NewPath("spec.hostPlacement.dedicatedHost"), "dedicatedHost is required when affinity is DedicatedHost, and forbidden otherwise"))
923+
} else {
924+
// If not set, return required error. If it does not match pattern, return pattern failure message.
925+
if placement.DedicatedHost.ID == "" {
926+
errs = append(errs, field.Required(field.NewPath("spec.hostPlacement.dedicatedHost.id"), "id is required and must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)"))
927+
} else if awsDedicatedHostNamePattern.FindStringSubmatch(placement.DedicatedHost.ID) == nil {
928+
errs = append(errs, field.Invalid(field.NewPath("spec.hostPlacement.dedicatedHost.id"), placement.DedicatedHost.ID, "id must start with 'h-' followed by 17 lowercase hexadecimal characters (0-9 and a-f)"))
929+
}
930+
}
931+
default:
932+
errs = append(errs, field.Invalid(field.NewPath("spec.hostPlacement.affinity"), placement.Affinity, "affinity must be either AnyAvailable or DedicatedHost"))
933+
}
934+
}
935+
}
936+
900937
if len(errs) > 0 {
901938
return false, warnings, errs
902939
}

0 commit comments

Comments
 (0)