diff --git a/cmd/config/go.mod b/cmd/config/go.mod index 19a5dbd6b..7e2ba5070 100644 --- a/cmd/config/go.mod +++ b/cmd/config/go.mod @@ -4,6 +4,7 @@ go 1.13 require ( github.com/go-errors/errors v1.0.1 + github.com/go-openapi/spec v0.19.5 github.com/olekukonko/tablewriter v0.0.4 github.com/posener/complete/v2 v2.0.1-alpha.12 github.com/spf13/cobra v1.0.0 diff --git a/cmd/config/internal/commands/cmdcreatesetter.go b/cmd/config/internal/commands/cmdcreatesetter.go index ec4297eb3..4a9db6a73 100644 --- a/cmd/config/internal/commands/cmdcreatesetter.go +++ b/cmd/config/internal/commands/cmdcreatesetter.go @@ -4,11 +4,15 @@ package commands import ( + "github.com/go-openapi/spec" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" + "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/setters" + "sigs.k8s.io/kustomize/kyaml/setters2" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil" ) @@ -86,12 +90,30 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error { if setterVersion == "v2" { var err error r.OpenAPIFile, err = ext.GetOpenAPIFile(args) - r.CreateSetter.Description = r.Set.SetPartialField.Description - r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy - r.CreateSetter.Type = r.Set.SetPartialField.Type if err != nil { return err } + + if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil { + return err + } + + // check if substitution with same name exists and throw error + ref, err := spec.NewRef(setters2.DefinitionsPrefix + setters2.SubstitutionDefinitionPrefix + r.CreateSetter.Name) + if err != nil { + return err + } + + subst, _ := openapi.Resolve(&ref) + // if substitution already exists with the input setter name, throw error + if subst != nil { + return errors.Errorf("substitution with name %s already exists, "+ + "substitution and setter can't have same name", r.CreateSetter.Name) + } + + r.CreateSetter.Description = r.Set.SetPartialField.Description + r.CreateSetter.SetBy = r.Set.SetPartialField.SetBy + r.CreateSetter.Type = r.Set.SetPartialField.Type } return nil } diff --git a/cmd/config/internal/commands/cmdcreatesetter_test.go b/cmd/config/internal/commands/cmdcreatesetter_test.go index ac4141cd0..9ec0e9451 100644 --- a/cmd/config/internal/commands/cmdcreatesetter_test.go +++ b/cmd/config/internal/commands/cmdcreatesetter_test.go @@ -22,8 +22,10 @@ func TestCreateSetterCommand(t *testing.T) { input string args []string out string + inputOpenAPI string expectedOpenAPI string expectedResources string + err string }{ { name: "add replicas", @@ -36,6 +38,10 @@ metadata: spec: replicas: 3 `, + inputOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +`, expectedOpenAPI: ` apiVersion: v1alpha1 kind: Example @@ -58,6 +64,27 @@ spec: replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"} `, }, + { + name: "error if substitution with same name exists", + args: []string{"my-image", "3", "--description", "hello world", "--set-by", "me"}, + inputOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +openAPI: + definitions: + io.k8s.cli.substitutions.my-image: + x-k8s-cli: + substitution: + name: my-image + pattern: something/${my-image-setter}::${my-tag-setter}/nginxotherthing + values: + - marker: ${my-image-setter} + ref: '#/definitions/io.k8s.cli.setters.my-image-setter' + - marker: ${my-tag-setter} + ref: '#/definitions/io.k8s.cli.setters.my-tag-setter' + `, + err: "substitution with name my-image already exists, substitution and setter can't have same name", + }, } for i := range tests { test := tests[i] @@ -71,10 +98,7 @@ spec: t.FailNow() } defer os.Remove(f.Name()) - err = ioutil.WriteFile(f.Name(), []byte(` -apiVersion: v1alpha1 -kind: Example -`), 0600) + err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600) if !assert.NoError(t, err) { t.FailNow() } @@ -99,6 +123,14 @@ kind: Example runner.Command.SetOut(out) runner.Command.SetArgs(append([]string{r.Name()}, test.args...)) err = runner.Command.Execute() + if test.err != "" { + if !assert.NotNil(t, err) { + t.FailNow() + } else { + assert.Equal(t, err.Error(), test.err) + return + } + } if !assert.NoError(t, err) { t.FailNow() } diff --git a/cmd/config/internal/commands/cmdcreatesubstitution.go b/cmd/config/internal/commands/cmdcreatesubstitution.go index d7a675a92..b4cb47988 100644 --- a/cmd/config/internal/commands/cmdcreatesubstitution.go +++ b/cmd/config/internal/commands/cmdcreatesubstitution.go @@ -4,12 +4,15 @@ package commands import ( + "fmt" "regexp" "strings" + "github.com/go-openapi/spec" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/kyaml/errors" + "sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/setters2" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil" ) @@ -63,6 +66,23 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro return err } + if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil { + return err + } + + // check if setter with same name exists and throw error + ref, err := spec.NewRef(setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix + r.CreateSubstitution.Name) + if err != nil { + return err + } + + setter, _ := openapi.Resolve(&ref) + // if setter already exists with input substitution name, throw error + if setter != nil { + return errors.Errorf(fmt.Sprintf("setter with name %s already exists, "+ + "substitution and setter can't have same name", r.CreateSubstitution.Name)) + } + // extract setter name tokens from pattern enclosed in ${} re := regexp.MustCompile(`\$\{([^}]*)\}`) markers := re.FindAll([]byte(r.CreateSubstitution.Pattern), -1) diff --git a/cmd/config/internal/commands/cmdcreatesubstitution_test.go b/cmd/config/internal/commands/cmdcreatesubstitution_test.go index 09a60c4bd..90ffc854b 100644 --- a/cmd/config/internal/commands/cmdcreatesubstitution_test.go +++ b/cmd/config/internal/commands/cmdcreatesubstitution_test.go @@ -25,6 +25,7 @@ func TestCreateSubstitutionCommand(t *testing.T) { out string expectedOpenAPI string expectedResources string + err string }{ { name: "substitution replicas", @@ -103,6 +104,23 @@ spec: image: sidecar:1.7.9 `, }, + { + name: "error if setter with same name exists", + args: []string{ + "my-image", "--field-value", "nginx:1.7.9", "--pattern", "${my-image-setter}:${my-tag-setter}"}, + inputOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +openAPI: + definitions: + io.k8s.cli.setters.my-image: + x-k8s-cli: + setter: + name: my-image + value: "nginx" + `, + err: "setter with name my-image already exists, substitution and setter can't have same name", + }, { name: "substitution and create setters 1", args: []string{ @@ -206,6 +224,14 @@ spec: runner.Command.SetOut(out) runner.Command.SetArgs(append([]string{r.Name()}, test.args...)) err = runner.Command.Execute() + + if test.err != "" { + if !assert.NotNil(t, err) { + t.FailNow() + } + assert.Equal(t, err.Error(), test.err) + return + } if !assert.NoError(t, err) { t.FailNow() }