diff --git a/cmd/config/internal/commands/cmdcreatesetter.go b/cmd/config/internal/commands/cmdcreatesetter.go index b107adea6..04ed314f3 100644 --- a/cmd/config/internal/commands/cmdcreatesetter.go +++ b/cmd/config/internal/commands/cmdcreatesetter.go @@ -128,9 +128,9 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error { r.CreateSetter.Type = r.Set.SetPartialField.Type if r.CreateSetter.Type == "array" { - // this is just a place holder value, we derive the actual value at - // later point from the field path - r.CreateSetter.FieldValue = "listValues" + if !c.Flag("field").Changed { + return errors.Errorf("field flag must be set for array type setters") + } } } return nil diff --git a/cmd/config/internal/commands/cmdcreatesetter_test.go b/cmd/config/internal/commands/cmdcreatesetter_test.go index 461a26db5..8547fb56b 100644 --- a/cmd/config/internal/commands/cmdcreatesetter_test.go +++ b/cmd/config/internal/commands/cmdcreatesetter_test.go @@ -129,8 +129,101 @@ spec: }, { - name: "add replicas with schema list values", - args: []string{"list", "a", "--description", "hello world", "--set-by", "me", "--type", "array", "--field", "spec.list"}, + name: "list values with schema", + args: []string{"list", "--description", "hello world", "--set-by", "me", "--type", "array", "--field", "spec.list"}, + schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`, + input: ` +apiVersion: example.com/v1beta1 +kind: Example1 +spec: + list: + - "a" + - "b" + - "c" +--- +apiVersion: example.com/v1beta1 +kind: Example2 +spec: + list: + - "a" + - "b" + - "c" + `, + inputOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +`, + expectedOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +openAPI: + definitions: + io.k8s.cli.setters.list: + items: + type: string + maxItems: 3 + type: array + description: hello world + x-k8s-cli: + setter: + name: list + value: "" + listValues: + - a + - b + - c + setBy: me + `, + expectedResources: ` +apiVersion: example.com/v1beta1 +kind: Example1 +spec: + list: # {"$openapi":"list"} + - "a" + - "b" + - "c" +--- +apiVersion: example.com/v1beta1 +kind: Example2 +spec: + list: # {"$openapi":"list"} + - "a" + - "b" + - "c" + `, + }, + + { + name: "error list path with different values", + args: []string{"list", "--description", "hello world", "--set-by", "me", "--type", "array", "--field", "spec.list"}, + schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`, + input: ` +apiVersion: example.com/v1beta1 +kind: Example +spec: + list: + - "a" + - "b" + - "c" +--- +apiVersion: example.com/v1beta1 +kind: Example +spec: + list: + - "c" + - "d" + `, + inputOpenAPI: ` +apiVersion: v1alpha1 +kind: Example +`, + err: `setters can only be created for fields with same values, encountered different ` + + `array values for specified field path: [c d], [a b c]`, + }, + + { + name: "list values error if field not set", + args: []string{"list", "a", "--description", "hello world", "--set-by", "me", "--type", "array"}, schema: `{"maxItems": 3, "type": "array", "items": {"type": "string"}}`, input: ` apiVersion: example.com/v1beta1 @@ -174,6 +267,7 @@ spec: - "b" - "c" `, + err: `field flag must be set for array type setters`, }, { name: "add replicas with value set by flag", diff --git a/cmd/config/internal/commands/cmdlistsetters_test.go b/cmd/config/internal/commands/cmdlistsetters_test.go index c870f73ec..4a1fc20d6 100644 --- a/cmd/config/internal/commands/cmdlistsetters_test.go +++ b/cmd/config/internal/commands/cmdlistsetters_test.go @@ -272,7 +272,6 @@ openAPI: x-k8s-cli: setter: name: list - value: List Values listValues: - a - b diff --git a/cmd/config/internal/commands/cmdset_test.go b/cmd/config/internal/commands/cmdset_test.go index eda1bd982..1191cd392 100644 --- a/cmd/config/internal/commands/cmdset_test.go +++ b/cmd/config/internal/commands/cmdset_test.go @@ -168,6 +168,7 @@ spec: replicas: 4 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"} `, }, + { name: "set image with value", args: []string{"tag", "1.8.1"}, diff --git a/kyaml/setters2/add.go b/kyaml/setters2/add.go index b7a7bf5a5..678fcaa89 100644 --- a/kyaml/setters2/add.go +++ b/kyaml/setters2/add.go @@ -4,6 +4,7 @@ package setters2 import ( + "reflect" "strings" "github.com/go-openapi/spec" @@ -33,6 +34,9 @@ type Add struct { // ListValues are the value of a list setter. ListValues []string + + // Type is the type of the setter value + Type string } // Filter implements yaml.Filter @@ -70,6 +74,12 @@ func (a *Add) visitMapping(object *yaml.RNode, p string, _ *openapi.ResourceSche for _, sc := range node.Value.Content() { values = append(values, sc.Value) } + + // check if there are different values for field path + if len(a.ListValues) > 0 && !reflect.DeepEqual(values, a.ListValues) { + return errors.Errorf("setters can only be created for fields with same values, "+ + "encountered different array values for specified field path: %s, %s", values, a.ListValues) + } a.ListValues = values // pathToKey refers to the path address of the key node ex: metadata.annotations @@ -86,6 +96,9 @@ func (a *Add) visitMapping(object *yaml.RNode, p string, _ *openapi.ResourceSche // visitScalar will set the field metadata on each scalar field whose name + value match func (a *Add) visitScalar(object *yaml.RNode, p string, _ *openapi.ResourceSchema) error { // check if the field matches + if a.Type == "array" { + return nil + } if a.FieldName != "" && !strings.HasSuffix(p, a.FieldName) { return nil } @@ -123,7 +136,7 @@ type SetterDefinition struct { Name string `yaml:"name"` // Value is the value of the setter. - Value string `yaml:"value,omitempty"` + Value string `yaml:"value"` // ListValues are the value of a list setter. ListValues []string `yaml:"listValues,omitempty"` diff --git a/kyaml/setters2/settersutil/settercreator.go b/kyaml/setters2/settersutil/settercreator.go index 200275a52..e2468922b 100644 --- a/kyaml/setters2/settersutil/settercreator.go +++ b/kyaml/setters2/settersutil/settercreator.go @@ -64,6 +64,7 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error { FieldName: c.FieldName, FieldValue: c.FieldValue, Ref: fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + c.Name, + Type: c.Type, } err = kio.Pipeline{ Inputs: []kio.Reader{inout},