From 29fbc564e31453b01c68946ded85af7ac64bc8cc Mon Sep 17 00:00:00 2001 From: Phani Teja Marupaka Date: Tue, 11 Feb 2020 09:22:38 -0800 Subject: [PATCH] Setter Definitions read and write --- kyaml/openapi/openapi.go | 35 ++++++++++ kyaml/openapi/openapi_test.go | 77 ++++++++++++++++++++++ kyaml/setters2/setterdefinition.go | 56 ++++++++++++++++ kyaml/setters2/setterdefinition_test.go | 88 +++++++++++++++++++++++++ 4 files changed, 256 insertions(+) create mode 100644 kyaml/setters2/setterdefinition.go create mode 100644 kyaml/setters2/setterdefinition_test.go diff --git a/kyaml/openapi/openapi.go b/kyaml/openapi/openapi.go index 7587968f1..7b93f7e07 100644 --- a/kyaml/openapi/openapi.go +++ b/kyaml/openapi/openapi.go @@ -291,6 +291,41 @@ func resolve(root interface{}, ref *spec.Ref) (*spec.Schema, error) { } } +func PopulateDefsInOpenAPI(s string) error { + y, err := yaml.Parse(s) + if err != nil { + return err + } + // get the field containing the openAPI + f := y.Field("openAPI") + + defs, err := f.Value.String() + if err != nil { + return err + } + + // convert the yaml openAPI to an interface{} + // which can be marshalled into json + var o interface{} + err = yaml.Unmarshal([]byte(defs), &o) + if err != nil { + return err + } + + // convert the interface{} into a json string + j, err := json.Marshal(o) + if err != nil { + return err + } + + // add the json schema to the global schema + _, err = AddSchema(j) + if err != nil { + return err + } + return nil +} + func rootSchema() *spec.Schema { initSchema() return &globalSchema.schema diff --git a/kyaml/openapi/openapi_test.go b/kyaml/openapi/openapi_test.go index 04bf26f0b..9e4bf455b 100644 --- a/kyaml/openapi/openapi_test.go +++ b/kyaml/openapi/openapi_test.go @@ -122,3 +122,80 @@ func TestSchemaForResourceType(t *testing.T) { t.FailNow() } } + +func TestPopulateDefsInOpenAPI_Setter(t *testing.T) { + globalSchema = openapiData{} + inputyaml := ` +openAPI: + definitions: + io.k8s.cli.setters.image-name: + x-k8s-cli: + setter: + name: image-name + value: "nginx" + ` + err := PopulateDefsInOpenAPI(inputyaml) + + if !assert.NoError(t, err) { + t.FailNow() + } + + s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.setters.image-name"}`) + + if !assert.NoError(t, err) { + t.FailNow() + } + if !assert.Greater(t, len(globalSchema.schema.Definitions), 200) { + t.FailNow() + } + assert.Equal(t, `map[x-k8s-cli:map[setter:map[name:image-name value:nginx]]]`, + fmt.Sprintf("%v", s.Schema.Extensions)) +} + +func TestPopulateDefsInOpenAPI_Substitution(t *testing.T) { + globalSchema = openapiData{} + inputyaml := ` +openAPI: + definitions: + io.k8s.cli.setters.image-name: + x-k8s-cli: + setter: + name: image-name + value: "nginx" + io.k8s.cli.setters.image-tag: + x-k8s-cli: + setter: + name: image-tag + value: "1.8.1" + io.k8s.cli.substitutions.image: + x-k8s-cli: + substitution: + name: image + pattern: IMAGE_NAME:IMAGE_TAG + values: + - marker: "IMAGE_NAME" + ref: "#/definitions/io.k8s.cli.setters.image-name" + - marker: "IMAGE_TAG" + ref: "#/definitions/io.k8s.cli.setters.image-tag" + ` + err := PopulateDefsInOpenAPI(inputyaml) + + if !assert.NoError(t, err) { + t.FailNow() + } + + s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.substitutions.image"}`) + + if !assert.NoError(t, err) { + t.FailNow() + } + if !assert.Greater(t, len(globalSchema.schema.Definitions), 200) { + t.FailNow() + } + + assert.Equal(t, + `map[x-k8s-cli:map[substitution:map[name:image pattern:IMAGE_NAME:IMAGE_TAG`+ + ` values:[map[marker:IMAGE_NAME ref:#/definitions/io.k8s.cli.setters.image-name]`+ + ` map[marker:IMAGE_TAG ref:#/definitions/io.k8s.cli.setters.image-tag]]]]]`, + fmt.Sprintf("%v", s.Schema.Extensions)) +} diff --git a/kyaml/setters2/setterdefinition.go b/kyaml/setters2/setterdefinition.go new file mode 100644 index 000000000..be8604dcf --- /dev/null +++ b/kyaml/setters2/setterdefinition.go @@ -0,0 +1,56 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package setters2 + +import ( + "io/ioutil" + + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +const DefinitionPrefix = "io.k8s.cli.setters." + +type SetterDefinition struct { + Name string + Value string +} + +func (sd SetterDefinition) AddSetterToFile(path string) error { + b, err := ioutil.ReadFile(path) + if err != nil { + return err + } + y, err := yaml.Parse(string(b)) + if err != nil { + return err + } + if err := y.PipeE(sd); err != nil { + return err + } + out, err := y.String() + if err != nil { + return err + } + if err := ioutil.WriteFile(path, []byte(out), 0600); err != nil { + return err + } + return nil +} + +func (sd SetterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) { + key := DefinitionPrefix + sd.Name + + def, err := object.Pipe(yaml.LookupCreate( + yaml.MappingNode, "openAPI", "definitions", key, "x-k8s-cli", "setter")) + if err != nil { + return nil, err + } + if err := def.PipeE(yaml.FieldSetter{Name: "name", StringValue: sd.Name}); err != nil { + return nil, err + } + if err := def.PipeE(yaml.FieldSetter{Name: "value", StringValue: sd.Value}); err != nil { + return nil, err + } + return object, nil +} diff --git a/kyaml/setters2/setterdefinition_test.go b/kyaml/setters2/setterdefinition_test.go new file mode 100644 index 000000000..2ea8ea151 --- /dev/null +++ b/kyaml/setters2/setterdefinition_test.go @@ -0,0 +1,88 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package setters2 + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +var kptfile = `apiVersion: kpt.dev/v1alpha1 +kind: Kptfile +metadata: + name: hello-world-set +upstream: + type: git + git: + commit: 5c1c019b59299a4f6c7edd1ff5ff54d720621bbe + repo: git@github.com:GoogleContainerTools/kpt + directory: /package-examples/helloworld-set + ref: v0.1.0 +packageMetadata: + shortDescription: example package using setters` + +func TestAddUpdateSetter(t *testing.T) { + path := os.TempDir() + "Kptfile" + + //write initial kptfile to temp path + err := ioutil.WriteFile(path, []byte(kptfile), 0600) + if !assert.NoError(t, err) { + t.FailNow() + } + + //add a setter definition + sd := SetterDefinition{ + Name: "no-match-1", + Value: "1", + } + + err = sd.AddSetterToFile(path) + + if !assert.NoError(t, err) { + t.FailNow() + } + + // update setter definition + sd2 := SetterDefinition{ + Name: "no-match-1", + Value: "2", + } + + err = sd2.AddSetterToFile(path) + + if !assert.NoError(t, err) { + t.FailNow() + } + + b, err := ioutil.ReadFile(path) + if err != nil { + t.FailNow() + } + + expected := `apiVersion: kpt.dev/v1alpha1 +kind: Kptfile +metadata: + name: hello-world-set +upstream: + type: git + git: + commit: 5c1c019b59299a4f6c7edd1ff5ff54d720621bbe + repo: git@github.com:GoogleContainerTools/kpt + directory: /package-examples/helloworld-set + ref: v0.1.0 +packageMetadata: + shortDescription: example package using setters +openAPI: + definitions: + io.k8s.cli.setters.no-match-1: + x-k8s-cli: + setter: + name: no-match-1 + value: 2 +` + assert.Equal(t, expected, string(b)) +}