diff --git a/cmd/config/internal/commands/cmdcreatesubstitution.go b/cmd/config/internal/commands/cmdcreatesubstitution.go index 66bbba070..d7a675a92 100644 --- a/cmd/config/internal/commands/cmdcreatesubstitution.go +++ b/cmd/config/internal/commands/cmdcreatesubstitution.go @@ -4,6 +4,7 @@ package commands import ( + "regexp" "strings" "github.com/spf13/cobra" @@ -17,20 +18,19 @@ import ( func NewCreateSubstitutionRunner(parent string) *CreateSubstitutionRunner { r := &CreateSubstitutionRunner{} cs := &cobra.Command{ - Use: "create-subst DIR NAME VALUE", - Args: cobra.ExactArgs(3), + Use: "create-subst DIR NAME", + Args: cobra.ExactArgs(2), PreRunE: r.preRunE, RunE: r.runE, } cs.Flags().StringVar(&r.CreateSubstitution.FieldName, "field", "", - "name of the field to set -- e.g. --field port") + "name of the field to set -- e.g. --field image") + cs.Flags().StringVar(&r.CreateSubstitution.FieldValue, "field-value", "", + "value of the field to create substitution for -- e.g. --field-value nginx:0.1.0") cs.Flags().StringVar(&r.CreateSubstitution.Pattern, "pattern", "", - "substitution pattern") - cs.Flags().StringSliceVar(&r.Values, "value", []string{""}, - "substitution values for the pattern. format is PATTERN_MARKER=SETTER_NAME"+ - "where PATTERN_MARKER is the pattern substring to replace, and SETTER_NAME is the"+ - "setter from which to take the replacement value.") + `substitution pattern -- e.g. --pattern \${my-image-setter}:\${my-tag-setter}`) _ = cs.MarkFlagRequired("pattern") + _ = cs.MarkFlagRequired("field-value") fixDocs(parent, cs) r.Command = cs return r @@ -54,7 +54,6 @@ func (r *CreateSubstitutionRunner) runE(c *cobra.Command, args []string) error { func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) error { var err error r.CreateSubstitution.Name = args[1] - r.CreateSubstitution.FieldValue = args[2] if err != nil { return err } @@ -64,16 +63,20 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro return err } - // parse the marker values - for i := range r.Values { - parts := strings.SplitN(r.Values[i], "=", 2) - if len(parts) < 2 { - return errors.Errorf("values must be specified as PATTERN_MARKER=SETTER_NAME") - } - ref := setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix + parts[1] + // extract setter name tokens from pattern enclosed in ${} + re := regexp.MustCompile(`\$\{([^}]*)\}`) + markers := re.FindAll([]byte(r.CreateSubstitution.Pattern), -1) + if len(markers) == 0 { + return errors.Errorf("unable to find setter names in pattern, " + + "setter names must be enclosed in ${}") + } + + for _, marker := range markers { + ref := setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix + + strings.TrimSuffix(strings.TrimPrefix(string(marker), "${"), "}") r.CreateSubstitution.Values = append( r.CreateSubstitution.Values, - setters2.Value{Marker: parts[0], Ref: ref}, + setters2.Value{Marker: string(marker), Ref: ref}, ) } diff --git a/cmd/config/internal/commands/cmdcreatesubstitution_test.go b/cmd/config/internal/commands/cmdcreatesubstitution_test.go index bc014d9c2..09a60c4bd 100644 --- a/cmd/config/internal/commands/cmdcreatesubstitution_test.go +++ b/cmd/config/internal/commands/cmdcreatesubstitution_test.go @@ -29,8 +29,7 @@ func TestCreateSubstitutionCommand(t *testing.T) { { name: "substitution replicas", args: []string{ - "image", "nginx:1.7.9", "--pattern", "IMAGE:TAG", - "--value", "IMAGE=image", "--value", "TAG=tag"}, + "my-image-subst", "--field-value", "nginx:1.7.9", "--pattern", "${my-image-setter}:${my-tag-setter}"}, input: ` apiVersion: apps/v1 kind: Deployment @@ -51,15 +50,15 @@ apiVersion: v1alpha1 kind: Example openAPI: definitions: - io.k8s.cli.setters.image: + io.k8s.cli.setters.my-image-setter: x-k8s-cli: setter: - name: image + name: my-image-setter value: "nginx" - io.k8s.cli.setters.tag: + io.k8s.cli.setters.my-tag-setter: x-k8s-cli: setter: - name: tag + name: my-tag-setter value: "1.7.9" `, expectedOpenAPI: ` @@ -67,26 +66,26 @@ apiVersion: v1alpha1 kind: Example openAPI: definitions: - io.k8s.cli.setters.image: + io.k8s.cli.setters.my-image-setter: x-k8s-cli: setter: - name: image + name: my-image-setter value: "nginx" - io.k8s.cli.setters.tag: + io.k8s.cli.setters.my-tag-setter: x-k8s-cli: setter: - name: tag + name: my-tag-setter value: "1.7.9" - io.k8s.cli.substitutions.image: + io.k8s.cli.substitutions.my-image-subst: x-k8s-cli: substitution: - name: image - pattern: IMAGE:TAG + name: my-image-subst + pattern: ${my-image-setter}:${my-tag-setter} values: - - marker: IMAGE - ref: '#/definitions/io.k8s.cli.setters.image' - - marker: TAG - ref: '#/definitions/io.k8s.cli.setters.tag' + - 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' `, expectedResources: ` apiVersion: apps/v1 @@ -99,7 +98,7 @@ spec: spec: containers: - name: nginx - image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.image"} + image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my-image-subst"} - name: sidecar image: sidecar:1.7.9 `, @@ -107,8 +106,7 @@ spec: { name: "substitution and create setters 1", args: []string{ - "image", "something/nginx::1.7.9/nginxotherthing", "--pattern", "something/IMAGE::TAG/nginxotherthing", - "--value", "IMAGE=image", "--value", "TAG=tag"}, + "my-image-subst", "--field-value", "something/nginx::1.7.9/nginxotherthing", "--pattern", "something/${my-image-setter}::${my-tag-setter}/nginxotherthing"}, input: ` apiVersion: apps/v1 kind: Deployment @@ -133,26 +131,26 @@ apiVersion: v1alpha1 kind: Example openAPI: definitions: - io.k8s.cli.setters.image: + io.k8s.cli.setters.my-image-setter: x-k8s-cli: setter: - name: image + name: my-image-setter value: nginx - io.k8s.cli.setters.tag: + io.k8s.cli.setters.my-tag-setter: x-k8s-cli: setter: - name: tag + name: my-tag-setter value: 1.7.9 - io.k8s.cli.substitutions.image: + io.k8s.cli.substitutions.my-image-subst: x-k8s-cli: substitution: - name: image - pattern: something/IMAGE::TAG/nginxotherthing + name: my-image-subst + pattern: something/${my-image-setter}::${my-tag-setter}/nginxotherthing values: - - marker: IMAGE - ref: '#/definitions/io.k8s.cli.setters.image' - - marker: TAG - ref: '#/definitions/io.k8s.cli.setters.tag' + - 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' `, expectedResources: ` apiVersion: apps/v1 @@ -165,7 +163,7 @@ spec: spec: containers: - name: nginx - image: something/nginx::1.7.9/nginxotherthing # {"$ref":"#/definitions/io.k8s.cli.substitutions.image"} + image: something/nginx::1.7.9/nginxotherthing # {"$ref":"#/definitions/io.k8s.cli.substitutions.my-image-subst"} - name: sidecar image: sidecar:1.7.9 `, diff --git a/kyaml/setters2/settersutil/substitutioncreator.go b/kyaml/setters2/settersutil/substitutioncreator.go index fc187c63e..e31cb8dd9 100644 --- a/kyaml/setters2/settersutil/substitutioncreator.go +++ b/kyaml/setters2/settersutil/substitutioncreator.go @@ -4,6 +4,7 @@ package settersutil import ( + "fmt" "strings" "sigs.k8s.io/kustomize/kyaml/errors" @@ -98,11 +99,14 @@ func (c SubstitutionCreator) CreateSettersForSubstitution(openAPIPath string) er } if obj == nil { + name := strings.TrimPrefix(value.Ref, "#/definitions/io.k8s.cli.setters.") + value := m[value.Marker] + fmt.Printf("unable to find setter with name %s, creating new setter with value %s\n", name, value) sd := setters2.SetterDefinition{ // get the setter name from ref. Ex: from #/definitions/io.k8s.cli.setters.image_setter // extract image_setter - Name: strings.TrimPrefix(value.Ref, "#/definitions/io.k8s.cli.setters."), - Value: m[value.Marker], + Name: name, + Value: value, } err := sd.AddToFile(openAPIPath) if err != nil {