From b40b67b9cfff1fdd6a1177372bdb545c5d2b6bbb Mon Sep 17 00:00:00 2001 From: Dan Bokete <150482588+DanBokete@users.noreply.github.com> Date: Sun, 21 Sep 2025 15:35:37 +0100 Subject: [PATCH] Deprecate caseless driver name validation and enforce lowercase warnings - Deprecate IsDNS1123SubdomainCaseless to avoid caseless validation issues. - Warn when ResourceSlice driver names contain uppercase characters. - Clarify driver names must be DNS subdomains and use only lowercase letters. - Update tests, staging code, and OpenAPI spec to reflect the changes. --- api/openapi-spec/swagger.json | 24 +++---- .../v3/apis__resource.k8s.io__v1_openapi.json | 8 +-- ...pis__resource.k8s.io__v1beta1_openapi.json | 8 +-- ...pis__resource.k8s.io__v1beta2_openapi.json | 8 +-- pkg/generated/openapi/zz_generated.openapi.go | 24 +++---- .../resource/resourceslice/strategy.go | 23 +++++- .../resource/resourceslice/strategy_test.go | 72 +++++++++++++++++++ .../k8s.io/api/resource/v1/generated.proto | 9 +-- staging/src/k8s.io/api/resource/v1/types.go | 9 +-- .../v1/types_swagger_doc_generated.go | 8 +-- .../api/resource/v1beta1/generated.proto | 9 +-- .../src/k8s.io/api/resource/v1beta1/types.go | 9 +-- .../v1beta1/types_swagger_doc_generated.go | 8 +-- .../api/resource/v1beta2/generated.proto | 9 +-- .../src/k8s.io/api/resource/v1beta2/types.go | 9 +-- .../v1beta2/types_swagger_doc_generated.go | 8 +-- .../pkg/api/validate/content/dns.go | 13 +++- .../resource/v1/allocateddevicestatus.go | 2 +- .../v1/devicerequestallocationresult.go | 2 +- .../resource/v1/opaquedeviceconfiguration.go | 2 +- .../resource/v1/resourceslicespec.go | 3 +- .../resource/v1beta1/allocateddevicestatus.go | 2 +- .../v1beta1/devicerequestallocationresult.go | 2 +- .../v1beta1/opaquedeviceconfiguration.go | 2 +- .../resource/v1beta1/resourceslicespec.go | 3 +- .../resource/v1beta2/allocateddevicestatus.go | 2 +- .../v1beta2/devicerequestallocationresult.go | 2 +- .../v1beta2/opaquedeviceconfiguration.go | 2 +- .../resource/v1beta2/resourceslicespec.go | 3 +- .../kubeletplugin/draplugin.go | 3 +- .../resourceslice/resourceslicecontroller.go | 2 + 31 files changed, 200 insertions(+), 90 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 8c5f82e53f4..28043b8fedf 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -15228,7 +15228,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -15792,7 +15792,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -16006,7 +16006,7 @@ "description": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "properties": { "driver": { - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -16357,7 +16357,7 @@ "x-kubernetes-list-type": "atomic" }, "driver": { - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { @@ -16577,7 +16577,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -17184,7 +17184,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -17352,7 +17352,7 @@ "description": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "properties": { "driver": { - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -17703,7 +17703,7 @@ "x-kubernetes-list-type": "atomic" }, "driver": { - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { @@ -17760,7 +17760,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -18324,7 +18324,7 @@ "type": "string" }, "driver": { - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -18538,7 +18538,7 @@ "description": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", "properties": { "driver": { - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -18889,7 +18889,7 @@ "x-kubernetes-list-type": "atomic" }, "driver": { - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1_openapi.json index 037b7403484..bf6f7f06f44 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1_openapi.json @@ -120,7 +120,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -859,7 +859,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -1124,7 +1124,7 @@ "properties": { "driver": { "default": "", - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -1585,7 +1585,7 @@ }, "driver": { "default": "", - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1beta1_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1beta1_openapi.json index 5463f30592f..30d9c9c5028 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1beta1_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1beta1_openapi.json @@ -120,7 +120,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -917,7 +917,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -1121,7 +1121,7 @@ "properties": { "driver": { "default": "", - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -1582,7 +1582,7 @@ }, "driver": { "default": "", - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1beta2_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1beta2_openapi.json index ca2bcc68e1d..df6d6de9ecf 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1beta2_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1beta2_openapi.json @@ -120,7 +120,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "networkData": { @@ -859,7 +859,7 @@ }, "driver": { "default": "", - "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "pool": { @@ -1124,7 +1124,7 @@ "properties": { "driver": { "default": "", - "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "description": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "type": "string" }, "parameters": { @@ -1585,7 +1585,7 @@ }, "driver": { "default": "", - "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "description": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "type": "string" }, "nodeName": { diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index ccc4bc0a153..e0e32a3016e 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -47989,7 +47989,7 @@ func schema_k8sio_api_resource_v1_AllocatedDeviceStatus(ref common.ReferenceCall Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -49086,7 +49086,7 @@ func schema_k8sio_api_resource_v1_DeviceRequestAllocationResult(ref common.Refer }, "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -49557,7 +49557,7 @@ func schema_k8sio_api_resource_v1_OpaqueDeviceConfiguration(ref common.Reference Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -50084,7 +50084,7 @@ func schema_k8sio_api_resource_v1_ResourceSliceSpec(ref common.ReferenceCallback Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", Default: "", Type: []string{"string"}, Format: "", @@ -50455,7 +50455,7 @@ func schema_k8sio_api_resource_v1beta1_AllocatedDeviceStatus(ref common.Referenc Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -51640,7 +51640,7 @@ func schema_k8sio_api_resource_v1beta1_DeviceRequestAllocationResult(ref common. }, "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -52022,7 +52022,7 @@ func schema_k8sio_api_resource_v1beta1_OpaqueDeviceConfiguration(ref common.Refe Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -52549,7 +52549,7 @@ func schema_k8sio_api_resource_v1beta1_ResourceSliceSpec(ref common.ReferenceCal Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", Default: "", Type: []string{"string"}, Format: "", @@ -52645,7 +52645,7 @@ func schema_k8sio_api_resource_v1beta2_AllocatedDeviceStatus(ref common.Referenc Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -53742,7 +53742,7 @@ func schema_k8sio_api_resource_v1beta2_DeviceRequestAllocationResult(ref common. }, "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -54213,7 +54213,7 @@ func schema_k8sio_api_resource_v1beta2_OpaqueDeviceConfiguration(ref common.Refe Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + Description: "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", Default: "", Type: []string{"string"}, Format: "", @@ -54740,7 +54740,7 @@ func schema_k8sio_api_resource_v1beta2_ResourceSliceSpec(ref common.ReferenceCal Properties: map[string]spec.Schema{ "driver": { SchemaProps: spec.SchemaProps{ - Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + Description: "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", Default: "", Type: []string{"string"}, Format: "", diff --git a/pkg/registry/resource/resourceslice/strategy.go b/pkg/registry/resource/resourceslice/strategy.go index 5df06d3e08e..0f5747a4229 100644 --- a/pkg/registry/resource/resourceslice/strategy.go +++ b/pkg/registry/resource/resourceslice/strategy.go @@ -19,6 +19,7 @@ package resourceslice import ( "context" "fmt" + "strings" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/fields" @@ -60,8 +61,17 @@ func (resourceSliceStrategy) Validate(ctx context.Context, obj runtime.Object) f return validation.ValidateResourceSlice(slice) } +// WarningsOnCreate returns warnings for the creation of the given object. func (resourceSliceStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string { - return nil + newResourceSlice := obj.(*resource.ResourceSlice) + var warnings []string + + if newResourceSlice.Spec.Driver != strings.ToLower(newResourceSlice.Spec.Driver) { + warnings = append(warnings, + fmt.Sprintf("spec.driver: driver names should be lowercase; %q contains uppercase characters", newResourceSlice.Spec.Driver)) + } + + return warnings } func (resourceSliceStrategy) Canonicalize(obj runtime.Object) { @@ -87,8 +97,17 @@ func (resourceSliceStrategy) ValidateUpdate(ctx context.Context, obj, old runtim return validation.ValidateResourceSliceUpdate(obj.(*resource.ResourceSlice), old.(*resource.ResourceSlice)) } +// WarningsOnUpdate returns warnings for the given update. func (resourceSliceStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.Object) []string { - return nil + newResourceSlice := obj.(*resource.ResourceSlice) + var warnings []string + + if newResourceSlice.Spec.Driver != strings.ToLower(newResourceSlice.Spec.Driver) { + warnings = append(warnings, + fmt.Sprintf("spec.driver: driver names should be lowercase; %q contains uppercase characters", newResourceSlice.Spec.Driver)) + } + + return warnings } func (resourceSliceStrategy) AllowUnconditionalUpdate() bool { diff --git a/pkg/registry/resource/resourceslice/strategy_test.go b/pkg/registry/resource/resourceslice/strategy_test.go index 9632624107b..9280cbf0cd5 100644 --- a/pkg/registry/resource/resourceslice/strategy_test.go +++ b/pkg/registry/resource/resourceslice/strategy_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" k8sresource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -669,3 +670,74 @@ func TestResourceSliceStrategyUpdate(t *testing.T) { }) } } + +func TestWarningsOnCreate(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + + testCases := map[string]struct { + obj *resource.ResourceSlice + wantWarningMessages []string + }{ + "valid driver": { + obj: slice, + wantWarningMessages: []string{}, + }, + "uppercase driver warning": { + obj: func() *resource.ResourceSlice { + obj := slice.DeepCopy() + obj.Spec.Driver = "Foo.COM" + return obj + }(), + wantWarningMessages: []string{ + `spec.driver: driver names should be lowercase; "Foo.COM" contains uppercase characters`, + }, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + warnings := Strategy.WarningsOnCreate(ctx, tc.obj) + if warnings == nil { + warnings = []string{} + } + require.Equal(t, tc.wantWarningMessages, warnings) + }) + } +} + +func TestWarningsOnUpdate(t *testing.T) { + ctx := genericapirequest.NewDefaultContext() + + testCases := map[string]struct { + newObj *resource.ResourceSlice + oldObj *resource.ResourceSlice + wantWarningMessages []string + }{ + "valid driver update": { + newObj: slice.DeepCopy(), + oldObj: slice.DeepCopy(), + wantWarningMessages: []string{}, + }, + "uppercase driver warning on update": { + newObj: func() *resource.ResourceSlice { + obj := slice.DeepCopy() + obj.Spec.Driver = "Foo.COM" + return obj + }(), + oldObj: slice.DeepCopy(), + wantWarningMessages: []string{ + `spec.driver: driver names should be lowercase; "Foo.COM" contains uppercase characters`, + }, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + warnings := Strategy.WarningsOnUpdate(ctx, tc.newObj, tc.oldObj) + if warnings == nil { + warnings = []string{} + } + require.Equal(t, tc.wantWarningMessages, warnings) + }) + } +} diff --git a/staging/src/k8s.io/api/resource/v1/generated.proto b/staging/src/k8s.io/api/resource/v1/generated.proto index e88673ac8d8..3b6d1310905 100644 --- a/staging/src/k8s.io/api/resource/v1/generated.proto +++ b/staging/src/k8s.io/api/resource/v1/generated.proto @@ -41,7 +41,7 @@ message AllocatedDeviceStatus { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -814,7 +814,7 @@ message DeviceRequestAllocationResult { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 2; @@ -1253,7 +1253,7 @@ message OpaqueDeviceConfiguration { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -1514,7 +1514,8 @@ message ResourceSliceSpec { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required optional string driver = 1; diff --git a/staging/src/k8s.io/api/resource/v1/types.go b/staging/src/k8s.io/api/resource/v1/types.go index feb633d0f98..b76e99ac863 100644 --- a/staging/src/k8s.io/api/resource/v1/types.go +++ b/staging/src/k8s.io/api/resource/v1/types.go @@ -101,7 +101,8 @@ type ResourceSliceSpec struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1268,7 +1269,7 @@ type OpaqueDeviceConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1494,7 +1495,7 @@ type DeviceRequestAllocationResult struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,2,name=driver"` @@ -1797,7 +1798,7 @@ type AllocatedDeviceStatus struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,rep,name=driver"` diff --git a/staging/src/k8s.io/api/resource/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1/types_swagger_doc_generated.go index bf81ced64ce..c37f64393fe 100644 --- a/staging/src/k8s.io/api/resource/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1/types_swagger_doc_generated.go @@ -29,7 +29,7 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllocatedDeviceStatus = map[string]string{ "": "AllocatedDeviceStatus contains the status of an allocated device, if the driver chooses to report it. This may include driver-specific information.\n\nThe combination of Driver, Pool, Device, and ShareID must match the corresponding key in Status.Allocation.Devices.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "shareID": "ShareID uniquely identifies an individual allocation share of the device.", @@ -277,7 +277,7 @@ func (DeviceRequest) SwaggerDoc() map[string]string { var map_DeviceRequestAllocationResult = map[string]string{ "": "DeviceRequestAllocationResult contains the allocation result for one request.", "request": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", @@ -369,7 +369,7 @@ func (NetworkDeviceData) SwaggerDoc() map[string]string { var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", - "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "parameters": "Parameters can contain arbitrary data. It is the responsibility of the driver developer to handle validation and versioning. Typically this includes self-identification and a version (\"kind\" + \"apiVersion\" for Kubernetes types), with conversion between different versions.\n\nThe length of the raw data must be smaller or equal to 10 Ki.", } @@ -493,7 +493,7 @@ func (ResourceSliceList) SwaggerDoc() map[string]string { var map_ResourceSliceSpec = map[string]string{ "": "ResourceSliceSpec contains the information published by the driver in one ResourceSlice.", - "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "pool": "Pool describes the pool that this ResourceSlice belongs to.", "nodeName": "NodeName identifies the node which provides the resources in this pool. A field selector can be used to list only ResourceSlice objects belonging to a certain node.\n\nThis field can be used to limit access from nodes to ResourceSlices with the same node name. It also indicates to autoscalers that adding new nodes of the same type as some old node might also make new resources available.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set. This field is immutable.", "nodeSelector": "NodeSelector defines which nodes have access to the resources in the pool, when that pool is not limited to a single node.\n\nMust use exactly one term.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set.", diff --git a/staging/src/k8s.io/api/resource/v1beta1/generated.proto b/staging/src/k8s.io/api/resource/v1beta1/generated.proto index 999e0b784c5..24ea8f070bf 100644 --- a/staging/src/k8s.io/api/resource/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/resource/v1beta1/generated.proto @@ -41,7 +41,7 @@ message AllocatedDeviceStatus { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -935,7 +935,7 @@ message DeviceRequestAllocationResult { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 2; @@ -1267,7 +1267,7 @@ message OpaqueDeviceConfiguration { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -1528,7 +1528,8 @@ message ResourceSliceSpec { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required optional string driver = 1; diff --git a/staging/src/k8s.io/api/resource/v1beta1/types.go b/staging/src/k8s.io/api/resource/v1beta1/types.go index b879721b87f..e955e0fa7b8 100644 --- a/staging/src/k8s.io/api/resource/v1beta1/types.go +++ b/staging/src/k8s.io/api/resource/v1beta1/types.go @@ -101,7 +101,8 @@ type ResourceSliceSpec struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1276,7 +1277,7 @@ type OpaqueDeviceConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1502,7 +1503,7 @@ type DeviceRequestAllocationResult struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,2,name=driver"` @@ -1805,7 +1806,7 @@ type AllocatedDeviceStatus struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,rep,name=driver"` diff --git a/staging/src/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go index 473fbb95031..bfddc82d9d6 100644 --- a/staging/src/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go @@ -29,7 +29,7 @@ package v1beta1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllocatedDeviceStatus = map[string]string{ "": "AllocatedDeviceStatus contains the status of an allocated device, if the driver chooses to report it. This may include driver-specific information.\n\nThe combination of Driver, Pool, Device, and ShareID must match the corresponding key in Status.Allocation.Devices.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "shareID": "ShareID uniquely identifies an individual allocation share of the device.", @@ -292,7 +292,7 @@ func (DeviceRequest) SwaggerDoc() map[string]string { var map_DeviceRequestAllocationResult = map[string]string{ "": "DeviceRequestAllocationResult contains the allocation result for one request.", "request": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", @@ -369,7 +369,7 @@ func (NetworkDeviceData) SwaggerDoc() map[string]string { var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", - "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "parameters": "Parameters can contain arbitrary data. It is the responsibility of the driver developer to handle validation and versioning. Typically this includes self-identification and a version (\"kind\" + \"apiVersion\" for Kubernetes types), with conversion between different versions.\n\nThe length of the raw data must be smaller or equal to 10 Ki.", } @@ -493,7 +493,7 @@ func (ResourceSliceList) SwaggerDoc() map[string]string { var map_ResourceSliceSpec = map[string]string{ "": "ResourceSliceSpec contains the information published by the driver in one ResourceSlice.", - "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "pool": "Pool describes the pool that this ResourceSlice belongs to.", "nodeName": "NodeName identifies the node which provides the resources in this pool. A field selector can be used to list only ResourceSlice objects belonging to a certain node.\n\nThis field can be used to limit access from nodes to ResourceSlices with the same node name. It also indicates to autoscalers that adding new nodes of the same type as some old node might also make new resources available.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set. This field is immutable.", "nodeSelector": "NodeSelector defines which nodes have access to the resources in the pool, when that pool is not limited to a single node.\n\nMust use exactly one term.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set.", diff --git a/staging/src/k8s.io/api/resource/v1beta2/generated.proto b/staging/src/k8s.io/api/resource/v1beta2/generated.proto index 10ffeca2eb1..b4ef6624012 100644 --- a/staging/src/k8s.io/api/resource/v1beta2/generated.proto +++ b/staging/src/k8s.io/api/resource/v1beta2/generated.proto @@ -41,7 +41,7 @@ message AllocatedDeviceStatus { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -814,7 +814,7 @@ message DeviceRequestAllocationResult { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 2; @@ -1253,7 +1253,7 @@ message OpaqueDeviceConfiguration { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required optional string driver = 1; @@ -1514,7 +1514,8 @@ message ResourceSliceSpec { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required optional string driver = 1; diff --git a/staging/src/k8s.io/api/resource/v1beta2/types.go b/staging/src/k8s.io/api/resource/v1beta2/types.go index 2e5c4505e3f..9ece337162e 100644 --- a/staging/src/k8s.io/api/resource/v1beta2/types.go +++ b/staging/src/k8s.io/api/resource/v1beta2/types.go @@ -101,7 +101,8 @@ type ResourceSliceSpec struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1268,7 +1269,7 @@ type OpaqueDeviceConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,name=driver"` @@ -1494,7 +1495,7 @@ type DeviceRequestAllocationResult struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,2,name=driver"` @@ -1797,7 +1798,7 @@ type AllocatedDeviceStatus struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. // // +required Driver string `json:"driver" protobuf:"bytes,1,rep,name=driver"` diff --git a/staging/src/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go index c390ad21d96..1b2ac954b0a 100644 --- a/staging/src/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go @@ -29,7 +29,7 @@ package v1beta2 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_AllocatedDeviceStatus = map[string]string{ "": "AllocatedDeviceStatus contains the status of an allocated device, if the driver chooses to report it. This may include driver-specific information.\n\nThe combination of Driver, Pool, Device, and ShareID must match the corresponding key in Status.Allocation.Devices.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "shareID": "ShareID uniquely identifies an individual allocation share of the device.", @@ -277,7 +277,7 @@ func (DeviceRequest) SwaggerDoc() map[string]string { var map_DeviceRequestAllocationResult = map[string]string{ "": "DeviceRequestAllocationResult contains the allocation result for one request.", "request": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", - "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", @@ -369,7 +369,7 @@ func (NetworkDeviceData) SwaggerDoc() map[string]string { var map_OpaqueDeviceConfiguration = map[string]string{ "": "OpaqueDeviceConfiguration contains configuration parameters for a driver in a format defined by the driver vendor.", - "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", + "driver": "Driver is used to determine which kubelet plugin needs to be passed these configuration parameters.\n\nAn admission policy provided by the driver developer could use this to decide whether it needs to validate them.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters.", "parameters": "Parameters can contain arbitrary data. It is the responsibility of the driver developer to handle validation and versioning. Typically this includes self-identification and a version (\"kind\" + \"apiVersion\" for Kubernetes types), with conversion between different versions.\n\nThe length of the raw data must be smaller or equal to 10 Ki.", } @@ -493,7 +493,7 @@ func (ResourceSliceList) SwaggerDoc() map[string]string { var map_ResourceSliceSpec = map[string]string{ "": "ResourceSliceSpec contains the information published by the driver in one ResourceSlice.", - "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. This field is immutable.", + "driver": "Driver identifies the DRA driver providing the capacity information. A field selector can be used to list only ResourceSlice objects with a certain driver name.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver. It should use only lower case characters. This field is immutable.", "pool": "Pool describes the pool that this ResourceSlice belongs to.", "nodeName": "NodeName identifies the node which provides the resources in this pool. A field selector can be used to list only ResourceSlice objects belonging to a certain node.\n\nThis field can be used to limit access from nodes to ResourceSlices with the same node name. It also indicates to autoscalers that adding new nodes of the same type as some old node might also make new resources available.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set. This field is immutable.", "nodeSelector": "NodeSelector defines which nodes have access to the resources in the pool, when that pool is not limited to a single node.\n\nMust use exactly one term.\n\nExactly one of NodeName, NodeSelector, AllNodes, and PerDeviceNodeSelection must be set.", diff --git a/staging/src/k8s.io/apimachinery/pkg/api/validate/content/dns.go b/staging/src/k8s.io/apimachinery/pkg/api/validate/content/dns.go index ddba8cbb310..bd20720794c 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/validate/content/dns.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/validate/content/dns.go @@ -67,9 +67,16 @@ func IsDNS1123Subdomain(value string) []string { // IsDNS1123SubdomainCaseless tests for a string that conforms to the definition of a // subdomain in DNS (RFC 1123). -// Deprecated: Use IsDNS1123Subdomain for strict, lowercase validation. -// Case-insensitive names are not recommended as they can lead to ambiguity -// (e.g., 'Foo', 'FOO', and 'foo' would be allowed names for foo). +// +// Deprecated: API validation should never be caseless. Caseless validation is a vector +// for bugs and failed uniqueness assumptions. For example, names like "foo.com" and +// "FOO.COM" are both accepted as valid, but they are typically not treated as equal by +// consumers (e.g. CSI and DRA driver names). This fails the "least surprise" principle and +// can cause inconsistent behaviors. +// +// Note: This allows uppercase names but is not caseless — uppercase and lowercase are +// treated as different values. Use IsDNS1123Subdomain for strict, lowercase validation +// instead. func IsDNS1123SubdomainCaseless(value string) []string { return isDNS1123Subdomain(value, true) } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/allocateddevicestatus.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/allocateddevicestatus.go index 93c412bd0e3..3b04727e345 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/allocateddevicestatus.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/allocateddevicestatus.go @@ -37,7 +37,7 @@ type AllocatedDeviceStatusApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go index d2ce324b9be..8b38fd28875 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/devicerequestallocationresult.go @@ -42,7 +42,7 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/opaquedeviceconfiguration.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/opaquedeviceconfiguration.go index d638ea74cff..4e2210d72f6 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/opaquedeviceconfiguration.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/opaquedeviceconfiguration.go @@ -35,7 +35,7 @@ type OpaqueDeviceConfigurationApplyConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // Parameters can contain arbitrary data. It is the responsibility of // the driver developer to handle validation and versioning. Typically this diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/resourceslicespec.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/resourceslicespec.go index ec1cccd184b..2c18db827af 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/resourceslicespec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1/resourceslicespec.go @@ -32,7 +32,8 @@ type ResourceSliceSpecApplyConfiguration struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. Driver *string `json:"driver,omitempty"` // Pool describes the pool that this ResourceSlice belongs to. Pool *ResourcePoolApplyConfiguration `json:"pool,omitempty"` diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocateddevicestatus.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocateddevicestatus.go index 11f112415fb..45b08dfe678 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocateddevicestatus.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/allocateddevicestatus.go @@ -37,7 +37,7 @@ type AllocatedDeviceStatusApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go index f44bca5ab44..2171522a35f 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicerequestallocationresult.go @@ -42,7 +42,7 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/opaquedeviceconfiguration.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/opaquedeviceconfiguration.go index 4db5dfb2e2f..ae8231f0b4f 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/opaquedeviceconfiguration.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/opaquedeviceconfiguration.go @@ -35,7 +35,7 @@ type OpaqueDeviceConfigurationApplyConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // Parameters can contain arbitrary data. It is the responsibility of // the driver developer to handle validation and versioning. Typically this diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/resourceslicespec.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/resourceslicespec.go index 0bdad64c406..f811c37a4a7 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/resourceslicespec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta1/resourceslicespec.go @@ -32,7 +32,8 @@ type ResourceSliceSpecApplyConfiguration struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. Driver *string `json:"driver,omitempty"` // Pool describes the pool that this ResourceSlice belongs to. Pool *ResourcePoolApplyConfiguration `json:"pool,omitempty"` diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocateddevicestatus.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocateddevicestatus.go index 46d94cbbc6e..4d7ba35c855 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocateddevicestatus.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocateddevicestatus.go @@ -37,7 +37,7 @@ type AllocatedDeviceStatusApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go index 04357de326c..c1fd0266f59 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go @@ -42,7 +42,7 @@ type DeviceRequestAllocationResultApplyConfiguration struct { // needed on a node. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // This name together with the driver name and the device name field // identify which device was allocated (`//`). diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/opaquedeviceconfiguration.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/opaquedeviceconfiguration.go index f0ff50f9bf2..d4ac456795d 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/opaquedeviceconfiguration.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/opaquedeviceconfiguration.go @@ -35,7 +35,7 @@ type OpaqueDeviceConfigurationApplyConfiguration struct { // to decide whether it needs to validate them. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. + // vendor of the driver. It should use only lower case characters. Driver *string `json:"driver,omitempty"` // Parameters can contain arbitrary data. It is the responsibility of // the driver developer to handle validation and versioning. Typically this diff --git a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslicespec.go b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslicespec.go index ed0363dfcb8..ca3e40b9deb 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslicespec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslicespec.go @@ -32,7 +32,8 @@ type ResourceSliceSpecApplyConfiguration struct { // objects with a certain driver name. // // Must be a DNS subdomain and should end with a DNS domain owned by the - // vendor of the driver. This field is immutable. + // vendor of the driver. It should use only lower case characters. + // This field is immutable. Driver *string `json:"driver,omitempty"` // Pool describes the pool that this ResourceSlice belongs to. Pool *ResourcePoolApplyConfiguration `json:"pool,omitempty"` diff --git a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go index 6f749116080..efb0755472c 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/kubeletplugin/draplugin.go @@ -205,7 +205,8 @@ type Device struct { type Option func(o *options) error // DriverName defines the driver name for the dynamic resource allocation driver. -// Must be set. +// Must be set. Must be a DNS subdomain and should end with a DNS domain +// owned by the vendor of the driver. It should use only lower case characters. func DriverName(driverName string) Option { return func(o *options) error { o.driverName = driverName diff --git a/staging/src/k8s.io/dynamic-resource-allocation/resourceslice/resourceslicecontroller.go b/staging/src/k8s.io/dynamic-resource-allocation/resourceslice/resourceslicecontroller.go index 271cbd7adf3..984cc57579d 100644 --- a/staging/src/k8s.io/dynamic-resource-allocation/resourceslice/resourceslicecontroller.go +++ b/staging/src/k8s.io/dynamic-resource-allocation/resourceslice/resourceslicecontroller.go @@ -194,6 +194,8 @@ func StartController(ctx context.Context, options Options) (*Controller, error) // Options contains various optional settings for [StartController]. type Options struct { // DriverName is the required name of the DRA driver. + // Must be a DNS subdomain and should end with a DNS domain + // owned by the vendor of the driver. It should use only lower case characters. DriverName string // KubeClient is used to read Node objects (if necessary) and to access