diff --git a/Makefile b/Makefile index aead579f8..0b60c007d 100644 --- a/Makefile +++ b/Makefile @@ -229,7 +229,8 @@ generate-kustomize-api: $(MYGOBIN)/k8scopy .PHONY: test-unit-kustomize-api test-unit-kustomize-api: build-kustomize-api - cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222" + cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"; \ + cd krusty; OPENAPI_TEST=true go test -run TestCustomOpenAPIFieldFromComponentWithOverlays .PHONY: test-unit-kustomize-plugins test-unit-kustomize-plugins: diff --git a/api/krusty/openapicustomschema_test.go b/api/krusty/openapicustomschema_test.go index 9e90e31d8..0e1844250 100644 --- a/api/krusty/openapicustomschema_test.go +++ b/api/krusty/openapicustomschema_test.go @@ -5,6 +5,7 @@ package krusty_test import ( "io/ioutil" + "os" "testing" "github.com/stretchr/testify/assert" @@ -346,3 +347,109 @@ func TestCustomOpenAPIFieldFromComponent(t *testing.T) { th.Run("prod", th.MakeDefaultOptions()) assert.Equal(t, "using custom schema from file provided", openapi.GetSchemaVersion()) } + +// test for https://github.com/kubernetes-sigs/kustomize/issues/4179 +// kustomize is not seeing the openapi field from the component defined in the overlay +func TestCustomOpenAPIFieldFromComponentWithOverlays(t *testing.T) { + if val, ok := os.LookupEnv("OPENAPI_TEST"); !ok || val != "true" { + t.SkipNow() + } + + th := kusttest_test.MakeHarness(t) + + // overlay declaring the component + th.WriteK("overlays/overlay-component-openapi", `resources: +- ../base/ +components: +- ../../components/dc-openapi +`) + + // base kustomization + th.WriteK("overlays/base", `resources: +- dc.yml +`) + + // resource declared in the base kustomization + th.WriteF("overlays/base/dc.yml", `apiVersion: apps.openshift.io/v1 +kind: DeploymentConfig +metadata: + name: my-dc +spec: + template: + spec: + initContainers: + - name: init + containers: + - name: container + env: + - name: foo + value: bar + volumeMounts: + - name: cm + mountPath: /opt/cm + volumes: + - name: cm + configMap: + name: cm +`) + + // openapi schema referred to by the component + bytes, _ := ioutil.ReadFile("testdata/openshiftschema.json") + th.WriteF("components/dc-openapi/openapi.json", string(bytes)) + + // patch referred to by the component + th.WriteF("components/dc-openapi/patch.yml", `apiVersion: apps.openshift.io/v1 +kind: DeploymentConfig +metadata: + name: my-dc +spec: + template: + spec: + containers: + - name: container + volumeMounts: + - name: additional-cm + mountPath: /mnt + volumes: + - name: additional-cm + configMap: + name: additional-cm +`) + + // component declared in overlay with custom schema and patch + th.WriteC("components/dc-openapi", `patches: + - patch.yml +openapi: + path: openapi.json +`) + + openapi.ResetOpenAPI() + m := th.Run("overlays/overlay-component-openapi", th.MakeDefaultOptions()) + th.AssertActualEqualsExpected(m, `apiVersion: apps.openshift.io/v1 +kind: DeploymentConfig +metadata: + name: my-dc +spec: + template: + spec: + containers: + - env: + - name: foo + value: bar + name: container + volumeMounts: + - mountPath: /mnt + name: additional-cm + - mountPath: /opt/cm + name: cm + initContainers: + - name: init + volumes: + - configMap: + name: additional-cm + name: additional-cm + - configMap: + name: cm + name: cm +`) +} diff --git a/api/krusty/testdata/openshiftschema.json b/api/krusty/testdata/openshiftschema.json new file mode 100644 index 000000000..b2efc185d --- /dev/null +++ b/api/krusty/testdata/openshiftschema.json @@ -0,0 +1,76 @@ +{ + "definitions": { + "com.github.openshift.api.apps.v1.DeploymentConfig": { + "type": "object", + "required": [ + "spec" + ], + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta" + }, + "spec": { + "$ref": "#/definitions/com.github.openshift.api.apps.v1.DeploymentConfigSpec" + } + }, + "x-kubernetes-group-version-kind": [ + { + "group": "apps.openshift.io", + "kind": "DeploymentConfig", + "version": "v1" + } + ] + }, + "com.github.openshift.api.apps.v1.DeploymentConfigSpec": { + "type": "object", + "properties": { + "template": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodTemplateSpec" + } + } + }, + "io.k8s.api.core.v1.Volume": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "configMap": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapVolumeSource" + }, + "name": { + "type": "string" + } + } + }, + "io.k8s.api.core.v1.VolumeMount": { + "type": "object", + "required": [ + "name", + "mountPath" + ], + "properties": { + "mountPath": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } +} diff --git a/kyaml/openapi/openapi.go b/kyaml/openapi/openapi.go index 6633b69c7..8b644166a 100644 --- a/kyaml/openapi/openapi.go +++ b/kyaml/openapi/openapi.go @@ -555,6 +555,8 @@ func SetSchema(openAPIField map[string]string, schema []byte, reset bool) error if schema != nil { // use custom schema customSchema = schema kubernetesOpenAPIVersion = "custom" + // if the schema is changed, initSchema should parse the new schema + globalSchema.schemaInit = false return nil } @@ -567,6 +569,8 @@ func SetSchema(openAPIField map[string]string, schema []byte, reset bool) error return fmt.Errorf("the specified OpenAPI version is not built in") } customSchema = nil + // if the schema is changed, initSchema should parse the new schema + globalSchema.schemaInit = false return nil }