Skip to content

Commit

Permalink
fix: Use correct type union in CRD spec for Quantity fields
Browse files Browse the repository at this point in the history
This fix sets the expected types based on the current K8S upstream OpenAPI v3 types:
https://github.com/kubernetes/kubernetes/blob/release-1.32/api/openapi-spec/v3/api__v1_openapi.json#L8637
  • Loading branch information
Stephen Heckler committed Dec 18, 2024
1 parent 0eec0d8 commit e7fa895
Show file tree
Hide file tree
Showing 8 changed files with 689 additions and 108 deletions.
360 changes: 330 additions & 30 deletions docs/features/kustomize/rollout_cr_schema.json

Large diffs are not rendered by default.

77 changes: 59 additions & 18 deletions hack/gen-crd-spec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ var preserveUnknownFields = map[string]any{
"x-kubernetes-preserve-unknown-fields": true,
}

const quantityType = `additionalProperties:
oneOf:
- type: string
- type: number
type: object`

var crdPaths = map[string]string{
"Rollout": "manifests/crds/rollout-crd.yaml",
"Experiment": "manifests/crds/experiment-crd.yaml",
Expand Down Expand Up @@ -221,36 +227,71 @@ func createMetadataValidation(un *unstructured.Unstructured) {
}
}

// setJsonStrOverride uses a JSON/YAML string to override the given path inside the object
func setJsonStrOverride(un *unstructured.Unstructured, override string, path string) {
overrideObj := unstructuredutil.StrToUnstructuredUnsafe(override)
// Prepare variables
preSchemaPath := []string{"spec", "versions"}
objVersions, _, _ := unstructured.NestedSlice(un.Object, preSchemaPath...)

schemaPath := []string{"schema", "openAPIV3Schema"}
for _, part := range strings.Split(path, ".") {
if strings.HasSuffix(part, "[]") {
part = strings.TrimSuffix(part, "[]")
schemaPath = append(schemaPath, "properties", part, "items")
} else {
schemaPath = append(schemaPath, "properties", part)
}
}

// Loop over version's slice
var finalOverride []interface{}
for _, v := range objVersions {
unstructured.SetNestedMap(v.(map[string]interface{}), overrideObj.Object, schemaPath...)

_, ok, err := unstructured.NestedFieldNoCopy(v.(map[string]interface{}), schemaPath...)
checkErr(err)
if !ok {
panic(fmt.Sprintf("%s not found for kind %s", schemaPath, crdKind(un)))
} else {
finalOverride = append(finalOverride, v)
}
}

// Write back to top object
unstructured.SetNestedSlice(un.Object, finalOverride, preSchemaPath...)
}

func removeK8S118Fields(un *unstructured.Unstructured) {
kind := crdKind(un)
switch kind {
case "Rollout":
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.containers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.containers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.initContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.initContainers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.ephemeralContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.ephemeralContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.template.spec.containers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.template.spec.containers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.template.spec.initContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.template.spec.initContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.template.spec.ephemeralContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.template.spec.ephemeralContainers[].resources.requests")
// Replace this with "spec.template.spec.volumes[].ephemeral.volumeClaimTemplate.spec.resources.{limits/requests}"
// when it's ok to only support k8s 1.17+
setValidationOverride(un, preserveUnknownFields, "spec.template.spec.volumes[]")
case "Experiment":
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.containers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.containers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.initContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.initContainers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.ephemeralContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.ephemeralContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.containers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.containers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.initContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.initContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.ephemeralContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.templates[].template.spec.ephemeralContainers[].resources.requests")
// Replace this with "spec.templates[].template.spec.volumes[].ephemeral.volumeClaimTemplate.spec.resources.{limits/requests}"
// when it's ok to only support k8s 1.17+
setValidationOverride(un, preserveUnknownFields, "spec.templates[].template.spec.volumes")
case "ClusterAnalysisTemplate", "AnalysisTemplate", "AnalysisRun":
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.containers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.containers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.initContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.initContainers[].resources.requests")
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.ephemeralContainers[].resources.limits")
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.ephemeralContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.containers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.containers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.initContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.initContainers[].resources.requests")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.ephemeralContainers[].resources.limits")
setJsonStrOverride(un, quantityType, "spec.metrics[].provider.job.spec.template.spec.ephemeralContainers[].resources.requests")
// Replace this with "spec.metrics[].provider.job.spec.template.spec.volumes[].ephemeral.volumeClaimTemplate.spec.resources.{limits/requests}"
// when it's ok to only support k8s 1.17+
setValidationOverride(un, preserveUnknownFields, "spec.metrics[].provider.job.spec.template.spec.volumes")
Expand Down
36 changes: 30 additions & 6 deletions manifests/crds/analysis-run-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1199,9 +1199,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -1847,9 +1855,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -2502,9 +2518,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down
36 changes: 30 additions & 6 deletions manifests/crds/analysis-template-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1195,9 +1195,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -1843,9 +1851,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -2498,9 +2514,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down
36 changes: 30 additions & 6 deletions manifests/crds/cluster-analysis-template-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1195,9 +1195,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -1843,9 +1851,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down Expand Up @@ -2498,9 +2514,17 @@ spec:
- name
x-kubernetes-list-type: map
limits:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
requests:
x-kubernetes-preserve-unknown-fields: true
additionalProperties:
oneOf:
- type: string
- type: number
type: object
type: object
restartPolicy:
type: string
Expand Down
Loading

0 comments on commit e7fa895

Please sign in to comment.