mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-17 17:52:12 +00:00
Refactor set
- Implement inline setters as OpenAPI extensions - Naming cleanup substitute -> set - Documentation cleanup - Simplify implementation
This commit is contained in:
73
cmd/config/internal/commands/cmdcreatesetter.go
Normal file
73
cmd/config/internal/commands/cmdcreatesetter.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||
)
|
||||
|
||||
// NewCreateSetterRunner returns a command runner.
|
||||
func NewCreateSetterRunner(parent string) *CreateSetterRunner {
|
||||
r := &CreateSetterRunner{}
|
||||
set := &cobra.Command{
|
||||
Use: "create-setter DIR NAME VALUE",
|
||||
Args: cobra.ExactArgs(3),
|
||||
Short: commands.CreateSetterShort,
|
||||
Long: commands.CreateSetterLong,
|
||||
Example: commands.CreateSetterExamples,
|
||||
PreRunE: r.preRunE,
|
||||
RunE: r.runE,
|
||||
}
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.SetBy, "set-by", "",
|
||||
"set the setBy annotation.")
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.Description, "description", "",
|
||||
"set the description of the field value.")
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.Field, "field", "",
|
||||
"name of the field to set -- e.g. --field port")
|
||||
set.Flags().StringVar(&r.Set.ResourceMeta.Name, "name", "",
|
||||
"name of the Resource on which to create the setter.")
|
||||
set.Flags().StringVar(&r.Set.ResourceMeta.Kind, "kind", "",
|
||||
"kind of the Resource on which to create the setter.")
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.Type, "type", "",
|
||||
"valid OpenAPI field type -- e.g. integer,boolean,string.")
|
||||
fixDocs(parent, set)
|
||||
set.MarkFlagRequired("type")
|
||||
set.MarkFlagRequired("field")
|
||||
r.Command = set
|
||||
return r
|
||||
}
|
||||
|
||||
func CreateSetterCommand(parent string) *cobra.Command {
|
||||
return NewCreateSetterRunner(parent).Command
|
||||
}
|
||||
|
||||
type CreateSetterRunner struct {
|
||||
Command *cobra.Command
|
||||
Set setters.CreateSetter
|
||||
}
|
||||
|
||||
func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
|
||||
return handleError(c, r.set(c, args))
|
||||
}
|
||||
|
||||
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
r.Set.SetPartialField.Setter.Name = args[1]
|
||||
r.Set.SetPartialField.Setter.Value = args[2]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CreateSetterRunner) set(c *cobra.Command, args []string) error {
|
||||
rw := &kio.LocalPackageReadWriter{PackagePath: args[0]}
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{rw},
|
||||
Filters: []kio.Filter{&r.Set},
|
||||
Outputs: []kio.Writer{rw}}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
120
cmd/config/internal/commands/cmdset.go
Normal file
120
cmd/config/internal/commands/cmdset.go
Normal file
@@ -0,0 +1,120 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||
)
|
||||
|
||||
// NewSetRunner returns a command runner.
|
||||
func NewSetRunner(parent string) *SetRunner {
|
||||
r := &SetRunner{}
|
||||
c := &cobra.Command{
|
||||
Use: "set DIR [NAME] [VALUE]",
|
||||
Args: cobra.RangeArgs(1, 3),
|
||||
Short: commands.SetShort,
|
||||
Long: commands.SetLong,
|
||||
Example: commands.SetExamples,
|
||||
PreRunE: r.preRunE,
|
||||
RunE: r.runE,
|
||||
}
|
||||
fixDocs(parent, c)
|
||||
r.Command = c
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func SetCommand(parent string) *cobra.Command {
|
||||
return NewSetRunner(parent).Command
|
||||
}
|
||||
|
||||
type SetRunner struct {
|
||||
Command *cobra.Command
|
||||
Lookup setters.LookupSetters
|
||||
Perform setters.PerformSetters
|
||||
}
|
||||
|
||||
func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
if len(args) > 1 {
|
||||
r.Perform.Name = args[1]
|
||||
r.Lookup.Name = args[1]
|
||||
}
|
||||
if len(args) > 2 {
|
||||
r.Perform.Value = args[2]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *SetRunner) runE(c *cobra.Command, args []string) error {
|
||||
|
||||
if len(args) == 3 {
|
||||
return handleError(c, r.perform(c, args))
|
||||
}
|
||||
|
||||
return handleError(c, r.lookup(c, args))
|
||||
}
|
||||
|
||||
func (r *SetRunner) lookup(c *cobra.Command, args []string) error {
|
||||
// lookup the setters
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: args[0]}},
|
||||
Filters: []kio.Filter{&r.Lookup},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(c.OutOrStdout())
|
||||
table.SetRowLine(false)
|
||||
table.SetBorder(false)
|
||||
table.SetHeaderLine(false)
|
||||
table.SetColumnSeparator(" ")
|
||||
table.SetCenterSeparator(" ")
|
||||
table.SetAlignment(tablewriter.ALIGN_LEFT)
|
||||
table.SetHeader([]string{
|
||||
"NAME", "DESCRIPTION", "VALUE", "TYPE", "COUNT", "SETBY",
|
||||
})
|
||||
for i := range r.Lookup.SetterCounts {
|
||||
s := r.Lookup.SetterCounts[i]
|
||||
v := s.Value
|
||||
if s.Value == "" {
|
||||
v = s.Value
|
||||
}
|
||||
table.Append([]string{
|
||||
s.Name,
|
||||
"'" + s.Description + "'",
|
||||
v,
|
||||
fmt.Sprintf("%v", s.Type),
|
||||
fmt.Sprintf("%d", s.Count),
|
||||
s.SetBy,
|
||||
})
|
||||
}
|
||||
table.Render()
|
||||
return nil
|
||||
}
|
||||
|
||||
// perform the setters
|
||||
func (r *SetRunner) perform(c *cobra.Command, args []string) error {
|
||||
rw := &kio.LocalPackageReadWriter{
|
||||
PackagePath: args[0],
|
||||
}
|
||||
// perform the setters in the package
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{rw},
|
||||
Filters: []kio.Filter{&r.Perform},
|
||||
Outputs: []kio.Writer{rw},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(c.OutOrStdout(), "set %d fields\n", r.Perform.Count)
|
||||
return nil
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/spf13/cobra"
|
||||
"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/set"
|
||||
)
|
||||
|
||||
// NewSubRunner returns a command runner.
|
||||
func NewSubRunner(parent string) *SubRunner {
|
||||
r := &SubRunner{}
|
||||
c := &cobra.Command{
|
||||
Use: "set DIR [NAME] [VALUE]",
|
||||
Args: cobra.RangeArgs(1, 3),
|
||||
Short: commands.SubShort,
|
||||
Long: commands.SubLong,
|
||||
Example: commands.SubExamples,
|
||||
Aliases: []string{"sub"},
|
||||
PreRunE: r.preRunE,
|
||||
RunE: r.runE,
|
||||
}
|
||||
c.Flags().BoolVar(&r.Perform.Override, "override", true,
|
||||
"override previously substituted values.")
|
||||
c.Flags().BoolVar(&r.Perform.Revert, "revert", false,
|
||||
"override previously substituted values.")
|
||||
fixDocs(parent, c)
|
||||
r.Command = c
|
||||
c.AddCommand(SubSetCommand(parent))
|
||||
return r
|
||||
}
|
||||
|
||||
func SubCommand(parent string) *cobra.Command {
|
||||
return NewSubRunner(parent).Command
|
||||
}
|
||||
|
||||
type SubRunner struct {
|
||||
Command *cobra.Command
|
||||
Lookup set.LookupSubstitutions
|
||||
Perform set.PerformSubstitutions
|
||||
}
|
||||
|
||||
func (r *SubRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
if len(args) > 1 {
|
||||
r.Perform.Name = args[1]
|
||||
r.Lookup.Name = args[1]
|
||||
}
|
||||
if len(args) > 2 {
|
||||
r.Perform.NewValue = args[2]
|
||||
}
|
||||
if len(args) < 2 && r.Perform.Revert {
|
||||
return errors.Errorf("must specify NAME with --revert")
|
||||
}
|
||||
|
||||
var mutex int
|
||||
if r.Perform.Revert {
|
||||
mutex++
|
||||
}
|
||||
if r.Perform.Override {
|
||||
mutex++
|
||||
}
|
||||
if mutex > 1 {
|
||||
return errors.Errorf("--revert, --override are mutually exclusive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *SubRunner) runE(c *cobra.Command, args []string) error {
|
||||
|
||||
if len(args) == 3 {
|
||||
return handleError(c, r.perform(c, args))
|
||||
}
|
||||
if len(args) == 2 && r.Perform.Revert {
|
||||
return handleError(c, r.perform(c, args))
|
||||
}
|
||||
|
||||
return handleError(c, r.lookup(c, args))
|
||||
}
|
||||
|
||||
func (r *SubRunner) lookup(c *cobra.Command, args []string) error {
|
||||
// lookup the substitutions
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: args[0]}},
|
||||
Filters: []kio.Filter{&r.Lookup},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remaining := false
|
||||
table := tablewriter.NewWriter(c.OutOrStdout())
|
||||
table.SetRowLine(false)
|
||||
table.SetBorder(false)
|
||||
table.SetHeaderLine(false)
|
||||
table.SetColumnSeparator(" ")
|
||||
table.SetCenterSeparator(" ")
|
||||
table.SetAlignment(tablewriter.ALIGN_LEFT)
|
||||
table.SetHeader([]string{
|
||||
"NAME", "DESCRIPTION", "VALUE", "TYPE", "COUNT", "SUBSTITUTED", "OWNER",
|
||||
})
|
||||
for i := range r.Lookup.SubstitutionCounts {
|
||||
s := r.Lookup.SubstitutionCounts[i]
|
||||
remaining = remaining || s.Count > s.CountComplete
|
||||
v := s.CurrentValue
|
||||
if s.CurrentValue == "" {
|
||||
v = s.Marker
|
||||
}
|
||||
table.Append([]string{
|
||||
s.Name,
|
||||
"'" + s.Description + "'",
|
||||
v,
|
||||
fmt.Sprintf("%v", s.Type),
|
||||
fmt.Sprintf("%d", s.Count),
|
||||
fmt.Sprintf("%v", s.Count == s.CountComplete),
|
||||
s.OwnedBy,
|
||||
})
|
||||
}
|
||||
table.Render()
|
||||
|
||||
if remaining {
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// perform the substitutions
|
||||
func (r *SubRunner) perform(c *cobra.Command, args []string) error {
|
||||
rw := &kio.LocalPackageReadWriter{
|
||||
PackagePath: args[0],
|
||||
}
|
||||
// perform the substitutions in the package
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{rw},
|
||||
Filters: []kio.Filter{&r.Perform},
|
||||
Outputs: []kio.Writer{rw},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(c.OutOrStdout(), "performed %d substitutions\n", r.Perform.Count)
|
||||
return nil
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright 2019 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/set"
|
||||
)
|
||||
|
||||
// NewSubSetRunner returns a command runner.
|
||||
func NewSubSetRunner(parent string) *SubSetRunner {
|
||||
r := &SubSetRunner{}
|
||||
set := &cobra.Command{
|
||||
Use: "create PKG_DIR NAME [VALUE]",
|
||||
Args: cobra.ExactArgs(3),
|
||||
Short: commands.SubsetShort,
|
||||
Long: commands.SubsetLong,
|
||||
Example: commands.SubsetExamples,
|
||||
PreRunE: r.preRunE,
|
||||
RunE: r.runE,
|
||||
}
|
||||
set.Flags().StringVar(&r.Set.Marker.OwnedBy, "owned-by", "",
|
||||
"set this owner on for the current value.")
|
||||
set.Flags().StringVar(&r.Set.Marker.Description, "description", "",
|
||||
"set this description for the current value description.")
|
||||
set.Flags().StringVar(&r.Set.Marker.Substitution.Marker, "marker", "[MARKER]",
|
||||
"use this marker.")
|
||||
set.Flags().StringVar(&r.Set.Marker.Field, "field", "",
|
||||
"name of the field to set -- e.g. --field port")
|
||||
set.Flags().StringVar(&r.Set.ResourceMeta.Name, "name", "",
|
||||
"name of the Resource on which to set the substitution.")
|
||||
set.Flags().StringVar(&r.Set.ResourceMeta.Kind, "kind", "",
|
||||
"kind of the Resource on which to set substitution.")
|
||||
set.Flags().StringVar(&r.Set.Marker.Type, "type", "",
|
||||
"field type -- e.g. int,float,bool,string.")
|
||||
set.Flags().BoolVar(&r.Set.Marker.PartialMatch, "substring", false,
|
||||
"if true, the value may be a substring of the current value.")
|
||||
fixDocs(parent, set)
|
||||
set.MarkFlagRequired("type")
|
||||
set.MarkFlagRequired("field")
|
||||
r.Command = set
|
||||
return r
|
||||
}
|
||||
|
||||
func SubSetCommand(parent string) *cobra.Command {
|
||||
return NewSubSetRunner(parent).Command
|
||||
}
|
||||
|
||||
type SubSetRunner struct {
|
||||
Command *cobra.Command
|
||||
Set set.SetSubstitutionMarker
|
||||
}
|
||||
|
||||
func (r *SubSetRunner) runE(c *cobra.Command, args []string) error {
|
||||
return handleError(c, r.set(c, args))
|
||||
}
|
||||
|
||||
func (r *SubSetRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
r.Set.Marker.Substitution.Name = args[1]
|
||||
r.Set.Marker.Substitution.Value = args[2]
|
||||
return nil
|
||||
}
|
||||
|
||||
// perform the substitutions
|
||||
func (r *SubSetRunner) set(c *cobra.Command, args []string) error {
|
||||
rw := &kio.LocalPackageReadWriter{
|
||||
PackagePath: args[0],
|
||||
}
|
||||
// add the substitution marker to the Resource
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{rw},
|
||||
Filters: []kio.Filter{&r.Set},
|
||||
Outputs: []kio.Writer{rw},
|
||||
}.Execute()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -49,6 +49,32 @@ var CountExamples = `
|
||||
# print Resource counts from a directory
|
||||
kustomize config count my-dir/`
|
||||
|
||||
var CreateSetterShort = `[Alpha] Create a custom setter for a Resource field`
|
||||
var CreateSetterLong = `
|
||||
Create a custom setter for a Resource field by inlining OpenAPI as comments.
|
||||
|
||||
DIR
|
||||
|
||||
A directory containing Resource configuration.
|
||||
|
||||
NAME
|
||||
|
||||
The name of the setter to create.
|
||||
|
||||
VALUE
|
||||
|
||||
The current value of the field, or a substring within the field.
|
||||
`
|
||||
var CreateSetterExamples = `
|
||||
# create a setter for port fields matching "8080"
|
||||
kustomize config create-setter DIR/ port 8080 --type "integer" --field port \
|
||||
--description "default port used by the app"
|
||||
|
||||
# create a setter for a substring of a field rather than the full field -- e.g. only the
|
||||
# image tag, not the full image
|
||||
kustomize config create-setter DIR/ image-tag v1.0.1 --type "string" \
|
||||
--field image --description "current stable release"`
|
||||
|
||||
var FmtShort = `[Alpha] Format yaml configuration files.`
|
||||
var FmtLong = `
|
||||
[Alpha] Format yaml configuration files.
|
||||
@@ -204,17 +230,18 @@ order they appear in the file).
|
||||
var RunFnsExamples = `
|
||||
kustomize config run example/`
|
||||
|
||||
var SubShort = `[Alpha] Set values on Resources fields by substituting values.`
|
||||
var SubLong = `
|
||||
Set values on Resources fields by substituting predefined markers for new values.
|
||||
var SetShort = `[Alpha] Set values on Resources fields values.`
|
||||
var SetLong = `
|
||||
Set values on Resources fields. May set either the complete or partial field value.
|
||||
|
||||
` + "`" + `set` + "`" + ` looks for markers specified on Resource fields and substitute a new user defined
|
||||
value for the existing value.
|
||||
` + "`" + `set` + "`" + ` identifies setters using field metadata published as OpenAPI extensions.
|
||||
` + "`" + `set` + "`" + ` parses both the Kubernetes OpenAPI, as well OpenAPI published inline in
|
||||
the configuration as comments.
|
||||
|
||||
` + "`" + `set` + "`" + ` maybe be used to:
|
||||
|
||||
- edit configuration programmatically from the cli or scripts
|
||||
- create reusable bundles of configuration
|
||||
- edit configuration programmatically from the cli
|
||||
- create reusable bundles of configuration with custom setters
|
||||
|
||||
DIR
|
||||
|
||||
@@ -222,244 +249,69 @@ value for the existing value.
|
||||
|
||||
NAME
|
||||
|
||||
Optional. The name of the substitution to perform or display.
|
||||
Optional. The name of the setter to perform or display.
|
||||
|
||||
VALUE
|
||||
|
||||
Optional. The new value to substitute into the field.
|
||||
Optional. The value to set on the field.
|
||||
|
||||
|
||||
To print the possible substitutions for the Resources in a directory, run ` + "`" + `set` + "`" + ` on
|
||||
To print the possible setters for the Resources in a directory, run ` + "`" + `set` + "`" + ` on
|
||||
a directory -- e.g. ` + "`" + `kustomize config set DIR/` + "`" + `.
|
||||
|
||||
#### Tips
|
||||
|
||||
- A description of the value may be specified with ` + "`" + `--description` + "`" + `.
|
||||
- An owner for the field's value may be defined with ` + "`" + `--owned-by` + "`" + `.
|
||||
- Prevent overriding previous substitutions with ` + "`" + `--override=false` + "`" + `.
|
||||
- Revert previous substitutions with ` + "`" + `--revert` + "`" + `.
|
||||
- Create substitutions on Kustomization.yaml's, patches, etc
|
||||
- The last setter for the field's value may be defined with ` + "`" + `--set-by` + "`" + `.
|
||||
- Create custom setters on Resources, Kustomization.yaml's, patches, etc
|
||||
|
||||
When overriding or reverting previous substitutions, the description and owner are left
|
||||
unmodified unless specified with flags.
|
||||
The description and setBy fields are left unmodified unless specified with flags.
|
||||
|
||||
To create a substitution for a field see: ` + "`" + `kustomize help config set create` + "`" + `
|
||||
To create a custom setter for a field see: ` + "`" + `kustomize help config create-setter` + "`" + `
|
||||
`
|
||||
var SubExamples = `
|
||||
Resource YAML: Name substitution
|
||||
var SetExamples = `
|
||||
Resource YAML: Name Prefix Setter
|
||||
|
||||
# dir/resources.yaml
|
||||
# DIR/resources.yaml
|
||||
...
|
||||
metadata:
|
||||
name: PREFIX-app1 # {"substitutions":[{"name":"prefix","marker":"PREFIX-"}]}
|
||||
name: PREFIX-app1 # {"type":"string","x-kustomize":{"partialFieldSetters":[{"name":"name-prefix","value":"PREFIX"}]}}
|
||||
...
|
||||
---
|
||||
...
|
||||
metadata:
|
||||
name: PREFIX-app2 # {"substitutions":[{"name":"prefix","marker":"PREFIX-"}]}
|
||||
name: PREFIX-app2 # {"type":"string","x-kustomize":{"partialFieldSetters":[{"name":"name-prefix","value":"PREFIX"}]}}
|
||||
...
|
||||
|
||||
Show substitutions: Show the possible substitutions
|
||||
List setters: Show the possible setters
|
||||
|
||||
$ config set dir
|
||||
NAME DESCRIPTION VALUE TYPE COUNT SUBSTITUTED OWNER
|
||||
prefix '' PREFIX- string 2 false
|
||||
$ config set DIR/
|
||||
NAME DESCRIPTION VALUE TYPE COUNT OWNER
|
||||
name-prefix '' PREFIX string 2
|
||||
|
||||
Perform substitution: set a new value, owner and description
|
||||
|
||||
$ config set dir prefix "test-" --description "test environment" --owned-by "dev"
|
||||
$ kustomize config set DIR/ name-prefix "test" --description "test environment" --set-by "dev"
|
||||
performed 2 substitutions
|
||||
|
||||
Show substitutions: Show the new values
|
||||
|
||||
$ config set dir
|
||||
NAME DESCRIPTION VALUE TYPE COUNT SUBSTITUTED OWNER
|
||||
prefix 'test environment' test- string 2 true dev
|
||||
prefix 'test environment' test string 2 true dev
|
||||
|
||||
New Resource YAML:
|
||||
|
||||
# dir/resources.yaml
|
||||
# DIR/resources.yaml
|
||||
...
|
||||
metadata:
|
||||
name: test-app1 # {"substitutions":[{"name":"prefix","marker":"PREFIX-","value":"test-"}],"setBy":"dev","description":"test environment"}
|
||||
name: test-app1 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","partialFieldSetters":[{"name":"name-prefix","value":"test"}]}}
|
||||
...
|
||||
---
|
||||
...
|
||||
metadata:
|
||||
name: test-app2 # {"substitutions":[{"name":"prefix","marker":"PREFIX-","value":"test-"}],"setBy":"dev","description":"test environment"}
|
||||
...
|
||||
|
||||
Revert substitution:
|
||||
|
||||
config set dir prefix --revert
|
||||
performed 2 substitutions
|
||||
|
||||
config set dir
|
||||
NAME DESCRIPTION VALUE TYPE COUNT SUBSTITUTED OWNER
|
||||
prefix 'test environment' PREFIX- string 2 false dev `
|
||||
|
||||
var SubsetShort = `[Alpha] Create a new substitution for a Resource field`
|
||||
var SubsetLong = `
|
||||
Create a new substitution for a Resource field -- recognized by ` + "`" + `kustomize config set` + "`" + `.
|
||||
|
||||
DIR
|
||||
|
||||
A directory containing Resource configuration.
|
||||
|
||||
NAME
|
||||
|
||||
The name of the substitution to create.
|
||||
|
||||
VALUE
|
||||
|
||||
The current value of the field, or a substring of the field.
|
||||
|
||||
#### Tips: Picking Good Marker
|
||||
|
||||
Substitutions may be defined by directly editing yaml **or** by running ` + "`" + `kustomize config set create` + "`" + `
|
||||
to create a new substitution.
|
||||
|
||||
Given the YAML:
|
||||
|
||||
# resource.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
...
|
||||
spec:
|
||||
...
|
||||
ports:
|
||||
...
|
||||
- name: http
|
||||
port: 8080
|
||||
...
|
||||
|
||||
Create a new set marker:
|
||||
|
||||
# create a substitution for ports
|
||||
$ kustomize config set create dir/ http-port 8080 --type "int" --field "port"
|
||||
|
||||
Modified YAML:
|
||||
|
||||
# resource.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
...
|
||||
spec:
|
||||
...
|
||||
ports:
|
||||
...
|
||||
- name: http
|
||||
port: 8080 # {"substitutions":[{"name":"port","marker":"[MARKER]"}],"type":"int"}
|
||||
...
|
||||
|
||||
Change the value using the ` + "`" + `set` + "`" + ` command:
|
||||
|
||||
# change the http-port value to 8081
|
||||
$ kustomize config set dir/ http-port 8081
|
||||
|
||||
Resources fields with a field name matching ` + "`" + `--field` + "`" + ` and field value matching ` + "`" + `VALUE` + "`" + ` will
|
||||
have a line comment added marking this field as settable.
|
||||
|
||||
Substitution markers may be:
|
||||
|
||||
- valid field values (e.g. ` + "`" + `8080` + "`" + ` for a port)
|
||||
- Note: ` + "`" + `008080` + "`" + ` would be preferred because it is more recognizable as a marker
|
||||
- invalid values that adhere to the schema (e.g. ` + "`" + `0000` + "`" + ` for a port)
|
||||
- values that do not adhere to the schema (e.g. ` + "`" + `[PORT]` + "`" + ` for port)
|
||||
|
||||
Markers **SHOULD be clearly identifiable as a marker and either**:
|
||||
|
||||
- **adhere to the field schema** -- e.g. use a valid value
|
||||
|
||||
|
||||
port: 008080 # {"substitutions":[{"name":"port","marker":"008080"}],"type":"int"}
|
||||
|
||||
- **be pre-filled in with a value** -- e.g. set the value when setting the marker
|
||||
|
||||
|
||||
port: 8080 # {"substitutions":[{"name":"port","marker":"[MARKER]","value":"8080""}],"type":"int"}
|
||||
|
||||
**Note:** The important thing is that in both cases the Resource configuration may be directly
|
||||
applied to a cluster and validated by tools without the tool knowing about the substitution
|
||||
marker.
|
||||
|
||||
The difference between the preceding examples is that:
|
||||
|
||||
- the former will be shown as ` + "`" + `SUBSTITUTED=false` + "`" + ` (` + "`" + `config sub dir/` + "`" + ` exits non-0)
|
||||
- the latter with show up as ` + "`" + `SUBSTITUTED=true` + "`" + ` (` + "`" + `config sub dir/` + "`" + ` exits 0)
|
||||
|
||||
When choosing the which to use, consider that checks for unsubstituted values MAY be
|
||||
configured as pre-commit checks -- if you want to these checks to fail if the value
|
||||
hasn't been substituted, then don't specify a ` + "`" + `value` + "`" + `.
|
||||
|
||||
Markers which are invalid field values MAY be chosen in cases where it is preferred to have
|
||||
the create or update request fail rather than succeed if the substitution has not yet been
|
||||
performed.
|
||||
|
||||
A substitution may be a substring of the full field:
|
||||
|
||||
$ kustomize config set create dir/ app-image-tag v1.0.01 --type "string" --field "image"
|
||||
|
||||
image: gcr.io/example/app:v1.0.1 # {"substitutions":[{"name":"app-image-tag","marker":"[MARKER]","value":"v1.0.1"}]}
|
||||
|
||||
|
||||
A single field value may have multiple substitutions applied to it:
|
||||
|
||||
name: PREFIX-app-SUFFIX # {"substitutions":[{"name":"prefix","marker":"PREFIX-"},{"name":"suffix","marker":"-SUFFIX"}]}
|
||||
|
||||
#### Substitution Format
|
||||
|
||||
Substitutions are defined as json encoded FieldMeta comments on fields.
|
||||
|
||||
FieldMeta Schema read by ` + "`" + `sub` + "`" + `:
|
||||
|
||||
{
|
||||
"title": "FieldMeta",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"substitutions": {
|
||||
"type": "array",
|
||||
"description": "Possible substitutions that may be performed against this field.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": "Name of the substitution.",
|
||||
"marker": "Marker for the value to be substituted.",
|
||||
"value": "Current substituted value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The value type. Defaults to string."
|
||||
"enum": ["string", "int", "float", "bool"]
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of the field's current value. Optional."
|
||||
},
|
||||
"setBy": {
|
||||
"type": "string",
|
||||
"description": "The current owner of the field. Optional."
|
||||
},
|
||||
}
|
||||
}
|
||||
`
|
||||
var SubsetExamples = `
|
||||
# set a substitution for port fields matching "8080"
|
||||
kustomize config sub create dir/ port 8080 --type "int" --field port \
|
||||
--description "default port used by the app"
|
||||
|
||||
# set a substitution for port fields matching "8080", using "0000" as a marker.
|
||||
kustomize config sub dir/ port 8080 --marker "0000" --type "int" \
|
||||
--field port --description "default port used by the app"
|
||||
|
||||
# substitute a substring of a field rather than the full field -- e.g. only the
|
||||
# image tag, not the full image
|
||||
kustomize config sub dir/ app-image-tag v1.0.1 --type "string" --substring \
|
||||
--field port --description "current stable release"`
|
||||
name: test-app2 # {"description":"test environment","type":"string","x-kustomize":{"setBy":"dev","partialFieldSetters":[{"name":"name-prefix","value":"test"}]}}
|
||||
...`
|
||||
|
||||
var TreeShort = `[Alpha] Display Resource structure from a directory or stdin.`
|
||||
var TreeLong = `
|
||||
|
||||
Reference in New Issue
Block a user