diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index f1931f1d769..b9291130b68 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -15852,7 +15852,7 @@ }, "parameters": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", - "description": "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." + "description": "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." } }, "required": [ @@ -16608,7 +16608,7 @@ }, "parameters": { "$ref": "#/definitions/io.k8s.apimachinery.pkg.runtime.RawExtension", - "description": "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." + "description": "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." } }, "required": [ diff --git a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json index f5c4d823edb..20162ac494c 100644 --- a/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json +++ b/api/openapi-spec/v3/apis__resource.k8s.io__v1alpha3_openapi.json @@ -586,7 +586,7 @@ "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" } ], - "description": "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." + "description": "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." } }, "required": [ 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 70434532371..d1051eafd73 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 @@ -608,7 +608,7 @@ "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.runtime.RawExtension" } ], - "description": "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." + "description": "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." } }, "required": [ diff --git a/pkg/apis/resource/types.go b/pkg/apis/resource/types.go index 741e2971df3..95377a45452 100644 --- a/pkg/apis/resource/types.go +++ b/pkg/apis/resource/types.go @@ -654,10 +654,16 @@ type OpaqueDeviceConfiguration struct { // includes self-identification and a version ("kind" + "apiVersion" for // Kubernetes types), with conversion between different versions. // + // The length of the raw data must be smaller or equal to 10 Ki. + // // +required Parameters runtime.RawExtension } +// OpaqueParametersMaxLength is the maximum length of the raw data in an +// [OpaqueDeviceConfiguration.Parameters] field. +const OpaqueParametersMaxLength = 10 * 1024 + // ResourceClaimStatus tracks whether the resource has been allocated and what // the result of that was. type ResourceClaimStatus struct { diff --git a/pkg/apis/resource/validation/validation.go b/pkg/apis/resource/validation/validation.go index 67dd89ea1b6..a12abf5a5c3 100644 --- a/pkg/apis/resource/validation/validation.go +++ b/pkg/apis/resource/validation/validation.go @@ -110,7 +110,7 @@ func validateDeviceClaim(deviceClaim *resource.DeviceClaim, fldPath *field.Path, }, fldPath.Child("constraints"))...) allErrs = append(allErrs, validateSlice(deviceClaim.Config, resource.DeviceConfigMaxSize, func(config resource.DeviceClaimConfiguration, fldPath *field.Path) field.ErrorList { - return validateDeviceClaimConfiguration(config, fldPath, requestNames) + return validateDeviceClaimConfiguration(config, fldPath, requestNames, stored) }, fldPath.Child("config"))...) return allErrs } @@ -212,13 +212,13 @@ func validateDeviceConstraint(constraint resource.DeviceConstraint, fldPath *fie return allErrs } -func validateDeviceClaimConfiguration(config resource.DeviceClaimConfiguration, fldPath *field.Path, requestNames sets.Set[string]) field.ErrorList { +func validateDeviceClaimConfiguration(config resource.DeviceClaimConfiguration, fldPath *field.Path, requestNames sets.Set[string], stored bool) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validateSet(config.Requests, resource.DeviceRequestsMaxSize, func(name string, fldPath *field.Path) field.ErrorList { return validateRequestNameRef(name, fldPath, requestNames) }, stringKey, fldPath.Child("requests"))...) - allErrs = append(allErrs, validateDeviceConfiguration(config.DeviceConfiguration, fldPath)...) + allErrs = append(allErrs, validateDeviceConfiguration(config.DeviceConfiguration, fldPath, stored)...) return allErrs } @@ -230,23 +230,29 @@ func validateRequestNameRef(name string, fldPath *field.Path, requestNames sets. return allErrs } -func validateDeviceConfiguration(config resource.DeviceConfiguration, fldPath *field.Path) field.ErrorList { +func validateDeviceConfiguration(config resource.DeviceConfiguration, fldPath *field.Path, stored bool) field.ErrorList { var allErrs field.ErrorList if config.Opaque == nil { allErrs = append(allErrs, field.Required(fldPath.Child("opaque"), "")) } else { - allErrs = append(allErrs, validateOpaqueConfiguration(*config.Opaque, fldPath.Child("opaque"))...) + allErrs = append(allErrs, validateOpaqueConfiguration(*config.Opaque, fldPath.Child("opaque"), stored)...) } return allErrs } -func validateOpaqueConfiguration(config resource.OpaqueDeviceConfiguration, fldPath *field.Path) field.ErrorList { +func validateOpaqueConfiguration(config resource.OpaqueDeviceConfiguration, fldPath *field.Path, stored bool) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validateDriverName(config.Driver, fldPath.Child("driver"))...) // Validation of RawExtension as in https://github.com/kubernetes/kubernetes/pull/125549/ var v any if len(config.Parameters.Raw) == 0 { allErrs = append(allErrs, field.Required(fldPath.Child("parameters"), "")) + } else if !stored && len(config.Parameters.Raw) > resource.OpaqueParametersMaxLength { + // Don't even bother with parsing when too large. + // Only applies on create. Existing parameters are grand-fathered in + // because the limit was introduced in 1.32. This also means that it + // can be changed in the future. + allErrs = append(allErrs, field.TooLong(fldPath.Child("parameters"), "" /* unused */, resource.OpaqueParametersMaxLength)) } else if err := json.Unmarshal(config.Parameters.Raw, &v); err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("parameters"), "", fmt.Sprintf("error parsing data as JSON: %v", err.Error()))) } else if v == nil { @@ -290,7 +296,7 @@ func validateResourceClaimStatusUpdate(status, oldStatus *resource.ResourceClaim if oldStatus.Allocation != nil && status.Allocation != nil { allErrs = append(allErrs, apimachineryvalidation.ValidateImmutableField(status.Allocation, oldStatus.Allocation, fldPath.Child("allocation"))...) } else if status.Allocation != nil { - allErrs = append(allErrs, validateAllocationResult(status.Allocation, fldPath.Child("allocation"), requestNames)...) + allErrs = append(allErrs, validateAllocationResult(status.Allocation, fldPath.Child("allocation"), requestNames, false)...) } return allErrs @@ -313,16 +319,16 @@ func validateResourceClaimUserReference(ref resource.ResourceClaimConsumerRefere // validateAllocationResult enforces constraints for *new* results, which in at // least one case (admin access) are more strict than before. Therefore it // may not be called to re-validate results which were stored earlier. -func validateAllocationResult(allocation *resource.AllocationResult, fldPath *field.Path, requestNames sets.Set[string]) field.ErrorList { +func validateAllocationResult(allocation *resource.AllocationResult, fldPath *field.Path, requestNames sets.Set[string], stored bool) field.ErrorList { var allErrs field.ErrorList - allErrs = append(allErrs, validateDeviceAllocationResult(allocation.Devices, fldPath.Child("devices"), requestNames)...) + allErrs = append(allErrs, validateDeviceAllocationResult(allocation.Devices, fldPath.Child("devices"), requestNames, stored)...) if allocation.NodeSelector != nil { allErrs = append(allErrs, corevalidation.ValidateNodeSelector(allocation.NodeSelector, fldPath.Child("nodeSelector"))...) } return allErrs } -func validateDeviceAllocationResult(allocation resource.DeviceAllocationResult, fldPath *field.Path, requestNames sets.Set[string]) field.ErrorList { +func validateDeviceAllocationResult(allocation resource.DeviceAllocationResult, fldPath *field.Path, requestNames sets.Set[string], stored bool) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validateSlice(allocation.Results, resource.AllocationResultsMaxSize, func(result resource.DeviceRequestAllocationResult, fldPath *field.Path) field.ErrorList { @@ -330,7 +336,7 @@ func validateDeviceAllocationResult(allocation resource.DeviceAllocationResult, }, fldPath.Child("results"))...) allErrs = append(allErrs, validateSlice(allocation.Config, 2*resource.DeviceConfigMaxSize, /* class + claim */ func(config resource.DeviceAllocationConfiguration, fldPath *field.Path) field.ErrorList { - return validateDeviceAllocationConfiguration(config, fldPath, requestNames) + return validateDeviceAllocationConfiguration(config, fldPath, requestNames, stored) }, fldPath.Child("config"))...) return allErrs @@ -345,14 +351,14 @@ func validateDeviceRequestAllocationResult(result resource.DeviceRequestAllocati return allErrs } -func validateDeviceAllocationConfiguration(config resource.DeviceAllocationConfiguration, fldPath *field.Path, requestNames sets.Set[string]) field.ErrorList { +func validateDeviceAllocationConfiguration(config resource.DeviceAllocationConfiguration, fldPath *field.Path, requestNames sets.Set[string], stored bool) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validateAllocationConfigSource(config.Source, fldPath.Child("source"))...) allErrs = append(allErrs, validateSet(config.Requests, resource.DeviceRequestsMaxSize, func(name string, fldPath *field.Path) field.ErrorList { return validateRequestNameRef(name, fldPath, requestNames) }, stringKey, fldPath.Child("requests"))...) - allErrs = append(allErrs, validateDeviceConfiguration(config.DeviceConfiguration, fldPath)...) + allErrs = append(allErrs, validateDeviceConfiguration(config.DeviceConfiguration, fldPath, stored)...) return allErrs } @@ -396,12 +402,20 @@ func validateDeviceClassSpec(spec, oldSpec *resource.DeviceClassSpec, fldPath *f return validateSelector(selector, fldPath, stored) }, fldPath.Child("selectors"))...) - allErrs = append(allErrs, validateSlice(spec.Config, resource.DeviceConfigMaxSize, validateDeviceClassConfiguration, fldPath.Child("config"))...) + // Same logic as above for configs. + if oldSpec != nil { + stored = apiequality.Semantic.DeepEqual(spec.Config, oldSpec.Config) + } + allErrs = append(allErrs, validateSlice(spec.Config, resource.DeviceConfigMaxSize, + func(config resource.DeviceClassConfiguration, fldPath *field.Path) field.ErrorList { + return validateDeviceClassConfiguration(config, fldPath, stored) + }, + fldPath.Child("config"))...) return allErrs } -func validateDeviceClassConfiguration(config resource.DeviceClassConfiguration, fldPath *field.Path) field.ErrorList { - return validateDeviceConfiguration(config.DeviceConfiguration, fldPath) +func validateDeviceClassConfiguration(config resource.DeviceClassConfiguration, fldPath *field.Path, stored bool) field.ErrorList { + return validateDeviceConfiguration(config.DeviceConfiguration, fldPath, stored) } // ValidateResourceClaimTemplate validates a ResourceClaimTemplate. diff --git a/pkg/apis/resource/validation/validation_deviceclass_test.go b/pkg/apis/resource/validation/validation_deviceclass_test.go index 3a09e2780ee..36c4acee5bb 100644 --- a/pkg/apis/resource/validation/validation_deviceclass_test.go +++ b/pkg/apis/resource/validation/validation_deviceclass_test.go @@ -17,6 +17,7 @@ limitations under the License. package validation import ( + "strings" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -227,6 +228,7 @@ func TestValidateClass(t *testing.T) { field.Invalid(field.NewPath("spec", "config").Index(3).Child("opaque", "parameters"), "", "parameters must be a valid JSON object"), field.Required(field.NewPath("spec", "config").Index(4).Child("opaque", "parameters"), ""), field.Required(field.NewPath("spec", "config").Index(5).Child("opaque"), ""), + field.TooLong(field.NewPath("spec", "config").Index(7).Child("opaque", "parameters"), "" /* unused */, resource.OpaqueParametersMaxLength), }, class: func() *resource.DeviceClass { class := testClass(goodName) @@ -272,6 +274,22 @@ func TestValidateClass(t *testing.T) { { DeviceConfiguration: resource.DeviceConfiguration{ /* Bad, empty. */ }, }, + { + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2) + `"}`)}, + }, + }, + }, + { + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }, } for i := len(class.Spec.Config); i < resource.DeviceConfigMaxSize; i++ { class.Spec.Config = append(class.Spec.Config, validConfig) @@ -321,6 +339,55 @@ func TestValidateClassUpdate(t *testing.T) { oldClass: validClass, update: func(class *resource.DeviceClass) *resource.DeviceClass { return class }, }, + "valid-config-large": { + oldClass: validClass, + update: func(class *resource.DeviceClass) *resource.DeviceClass { + class.Spec.Config = []resource.DeviceClassConfiguration{{ + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2) + `"}`)}, + }, + }, + }} + return class + }, + }, + "invalid-config-too-large": { + wantFailures: field.ErrorList{ + field.TooLong(field.NewPath("spec", "config").Index(0).Child("opaque", "parameters"), "" /* unused */, resource.OpaqueParametersMaxLength), + }, + oldClass: validClass, + update: func(class *resource.DeviceClass) *resource.DeviceClass { + class.Spec.Config = []resource.DeviceClassConfiguration{{ + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }} + return class + }, + }, + "too-large-config-valid-if-stored": { + oldClass: func() *resource.DeviceClass { + class := validClass.DeepCopy() + class.Spec.Config = []resource.DeviceClassConfiguration{{ + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }} + return class + }(), + update: func(class *resource.DeviceClass) *resource.DeviceClass { + // No changes -> remains valid. + return class + }, + }, } for name, scenario := range scenarios { diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index ee7edbe385f..ce29a0106a7 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -393,12 +393,13 @@ func TestValidateClaim(t *testing.T) { return claim }(), }, - "invalid-config-json": { + "configuration": { wantFailures: field.ErrorList{ field.Required(field.NewPath("spec", "devices", "config").Index(0).Child("opaque", "parameters"), ""), field.Invalid(field.NewPath("spec", "devices", "config").Index(1).Child("opaque", "parameters"), "", "error parsing data as JSON: unexpected end of JSON input"), field.Invalid(field.NewPath("spec", "devices", "config").Index(2).Child("opaque", "parameters"), "", "parameters must be a valid JSON object"), field.Required(field.NewPath("spec", "devices", "config").Index(3).Child("opaque", "parameters"), ""), + field.TooLong(field.NewPath("spec", "devices", "config").Index(5).Child("opaque", "parameters"), "" /* unused */, resource.OpaqueParametersMaxLength), }, claim: func() *resource.ResourceClaim { claim := testClaim(goodName, goodNS, validClaimSpec) @@ -443,6 +444,26 @@ func TestValidateClaim(t *testing.T) { }, }, }, + { + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: "dra.example.com", + Parameters: runtime.RawExtension{ + Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2) + `"}`), + }, + }, + }, + }, + { + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: "dra.example.com", + Parameters: runtime.RawExtension{ + Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`), + }, + }, + }, + }, } return claim }(), @@ -534,7 +555,7 @@ func TestValidateClaimUpdate(t *testing.T) { oldClaim: validClaim, update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { return claim }, }, - "invalid-update-class": { + "invalid-update": { wantFailures: field.ErrorList{field.Invalid(field.NewPath("spec"), func() resource.ResourceClaimSpec { spec := validClaim.Spec.DeepCopy() spec.Devices.Requests[0].DeviceClassName += "2" @@ -546,6 +567,24 @@ func TestValidateClaimUpdate(t *testing.T) { return claim }, }, + "too-large-config-valid-if-stored": { + oldClaim: func() *resource.ResourceClaim { + claim := validClaim.DeepCopy() + claim.Spec.Devices.Config = []resource.DeviceClaimConfiguration{{ + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }} + return claim + }(), + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + // No changes -> remains valid. + return claim + }, + }, } for name, scenario := range scenarios { @@ -849,6 +888,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) { field.Required(field.NewPath("status", "allocation", "devices", "config").Index(4).Child("opaque", "driver"), ""), field.Invalid(field.NewPath("status", "allocation", "devices", "config").Index(4).Child("opaque", "driver"), "", "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"), field.Required(field.NewPath("status", "allocation", "devices", "config").Index(4).Child("opaque", "parameters"), ""), + field.TooLong(field.NewPath("status", "allocation", "devices", "config").Index(6).Child("opaque", "parameters"), "" /* unused */, resource.OpaqueParametersMaxLength), }, oldClaim: validClaim, update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { @@ -898,11 +938,51 @@ func TestValidateClaimStatusUpdate(t *testing.T) { Opaque: &resource.OpaqueDeviceConfiguration{ /* Empty! */ }, }, }, + { + Source: resource.AllocationConfigSourceClaim, + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2) + `"}`)}, + }, + }, + }, + { + Source: resource.AllocationConfigSourceClaim, + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }, // Other invalid resource.DeviceConfiguration are covered elsewhere. */ } return claim }, }, + "valid-configuration-update": { + oldClaim: func() *resource.ResourceClaim { + claim := validClaim.DeepCopy() + claim.Status.Allocation = validAllocatedClaim.Status.Allocation.DeepCopy() + claim.Status.Allocation.Devices.Config = []resource.DeviceAllocationConfiguration{ + { + Source: resource.AllocationConfigSourceClaim, + DeviceConfiguration: resource.DeviceConfiguration{ + Opaque: &resource.OpaqueDeviceConfiguration{ + Driver: goodName, + Parameters: runtime.RawExtension{Raw: []byte(`{"str": "` + strings.Repeat("x", resource.OpaqueParametersMaxLength-9-2+1 /* too large by one */) + `"}`)}, + }, + }, + }, + } + return claim + }(), + update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { + // No change -> remains valid. + return claim + }, + }, } for name, scenario := range scenarios { diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index d49e1c9f1b5..759f7f585d2 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -47061,7 +47061,7 @@ func schema_k8sio_api_resource_v1alpha3_OpaqueDeviceConfiguration(ref common.Ref }, "parameters": { SchemaProps: spec.SchemaProps{ - Description: "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.", + Description: "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.", Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, @@ -48413,7 +48413,7 @@ func schema_k8sio_api_resource_v1beta1_OpaqueDeviceConfiguration(ref common.Refe }, "parameters": { SchemaProps: spec.SchemaProps{ - Description: "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.", + Description: "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.", Ref: ref("k8s.io/apimachinery/pkg/runtime.RawExtension"), }, }, diff --git a/staging/src/k8s.io/api/resource/v1alpha3/generated.proto b/staging/src/k8s.io/api/resource/v1alpha3/generated.proto index 2315bde82c2..253bf17ba39 100644 --- a/staging/src/k8s.io/api/resource/v1alpha3/generated.proto +++ b/staging/src/k8s.io/api/resource/v1alpha3/generated.proto @@ -500,6 +500,8 @@ message OpaqueDeviceConfiguration { // includes self-identification and a version ("kind" + "apiVersion" for // Kubernetes types), with conversion between different versions. // + // The length of the raw data must be smaller or equal to 10 Ki. + // // +required optional .k8s.io.apimachinery.pkg.runtime.RawExtension parameters = 2; } diff --git a/staging/src/k8s.io/api/resource/v1alpha3/types.go b/staging/src/k8s.io/api/resource/v1alpha3/types.go index 1efeceff084..bae302e6b84 100644 --- a/staging/src/k8s.io/api/resource/v1alpha3/types.go +++ b/staging/src/k8s.io/api/resource/v1alpha3/types.go @@ -652,10 +652,16 @@ type OpaqueDeviceConfiguration struct { // includes self-identification and a version ("kind" + "apiVersion" for // Kubernetes types), with conversion between different versions. // + // The length of the raw data must be smaller or equal to 10 Ki. + // // +required Parameters runtime.RawExtension `json:"parameters" protobuf:"bytes,2,name=parameters"` } +// OpaqueParametersMaxLength is the maximum length of the raw data in an +// [OpaqueDeviceConfiguration.Parameters] field. +const OpaqueParametersMaxLength = 10 * 1024 + // ResourceClaimStatus tracks whether the resource has been allocated and what // the result of that was. type ResourceClaimStatus struct { diff --git a/staging/src/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go b/staging/src/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go index 9e549189c7d..f9a9614e34e 100644 --- a/staging/src/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go @@ -214,7 +214,7 @@ func (DeviceSelector) 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.", - "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.", + "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.", } func (OpaqueDeviceConfiguration) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/api/resource/v1beta1/generated.proto b/staging/src/k8s.io/api/resource/v1beta1/generated.proto index 536c2bd1688..af1ed4f144d 100644 --- a/staging/src/k8s.io/api/resource/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/resource/v1beta1/generated.proto @@ -508,6 +508,8 @@ message OpaqueDeviceConfiguration { // includes self-identification and a version ("kind" + "apiVersion" for // Kubernetes types), with conversion between different versions. // + // The length of the raw data must be smaller or equal to 10 Ki. + // // +required optional .k8s.io.apimachinery.pkg.runtime.RawExtension parameters = 2; } diff --git a/staging/src/k8s.io/api/resource/v1beta1/types.go b/staging/src/k8s.io/api/resource/v1beta1/types.go index 205bef07b08..075ba0cda2b 100644 --- a/staging/src/k8s.io/api/resource/v1beta1/types.go +++ b/staging/src/k8s.io/api/resource/v1beta1/types.go @@ -660,10 +660,16 @@ type OpaqueDeviceConfiguration struct { // includes self-identification and a version ("kind" + "apiVersion" for // Kubernetes types), with conversion between different versions. // + // The length of the raw data must be smaller or equal to 10 Ki. + // // +required Parameters runtime.RawExtension `json:"parameters" protobuf:"bytes,2,name=parameters"` } +// OpaqueParametersMaxLength is the maximum length of the raw data in an +// [OpaqueDeviceConfiguration.Parameters] field. +const OpaqueParametersMaxLength = 10 * 1024 + // ResourceClaimStatus tracks whether the resource has been allocated and what // the result of that was. type ResourceClaimStatus struct { 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 6a4127ce111..72c40609612 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 @@ -223,7 +223,7 @@ func (DeviceSelector) 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.", - "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.", + "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.", } func (OpaqueDeviceConfiguration) SwaggerDoc() map[string]string {