mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-17 17:52:12 +00:00
Merge pull request #2439 from phanimarupaka/ListSubstitions
List substitutions
This commit is contained in:
@@ -10,7 +10,7 @@ require (
|
|||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
k8s.io/apimachinery v0.17.0
|
k8s.io/apimachinery v0.17.0
|
||||||
sigs.k8s.io/kustomize/kyaml v0.0.0
|
sigs.k8s.io/kustomize/kyaml v0.1.7
|
||||||
)
|
)
|
||||||
|
|
||||||
replace sigs.k8s.io/kustomize/kyaml v0.0.0 => ../../kyaml
|
replace sigs.k8s.io/kustomize/kyaml v0.1.7 => ../../kyaml
|
||||||
|
|||||||
@@ -168,6 +168,8 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
|
|||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||||
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
|||||||
@@ -59,42 +59,83 @@ func (r *ListSettersRunner) preRunE(c *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
|
func (r *ListSettersRunner) runE(c *cobra.Command, args []string) error {
|
||||||
if setterVersion == "v2" {
|
if setterVersion == "v2" {
|
||||||
// use setters v2
|
if err := r.ListSetters(c, args); err != nil {
|
||||||
path, err := ext.GetOpenAPIFile(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := r.List.List(path, args[0]); err != nil {
|
return r.ListSubstitutions(c, args)
|
||||||
return err
|
|
||||||
}
|
|
||||||
table := newTable(c.OutOrStdout(), r.Markdown)
|
|
||||||
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT"})
|
|
||||||
for i := range r.List.Setters {
|
|
||||||
s := r.List.Setters[i]
|
|
||||||
v := s.Value
|
|
||||||
|
|
||||||
// if the setter is for a list, populate the values
|
|
||||||
if len(s.ListValues) > 0 {
|
|
||||||
v = strings.Join(s.ListValues, ",")
|
|
||||||
v = fmt.Sprintf("[%s]", v)
|
|
||||||
}
|
|
||||||
table.Append([]string{
|
|
||||||
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count)})
|
|
||||||
}
|
|
||||||
table.Render()
|
|
||||||
|
|
||||||
if len(r.List.Setters) == 0 {
|
|
||||||
// exit non-0 if no matching setters are found
|
|
||||||
if ExitOnError {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleError(c, lookup(r.Lookup, c, args))
|
return handleError(c, lookup(r.Lookup, c, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ListSettersRunner) ListSetters(c *cobra.Command, args []string) error {
|
||||||
|
// use setters v2
|
||||||
|
path, err := ext.GetOpenAPIFile(args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.List.ListSetters(path, args[0]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
table := newTable(c.OutOrStdout(), r.Markdown)
|
||||||
|
table.SetHeader([]string{"NAME", "VALUE", "SET BY", "DESCRIPTION", "COUNT"})
|
||||||
|
for i := range r.List.Setters {
|
||||||
|
s := r.List.Setters[i]
|
||||||
|
v := s.Value
|
||||||
|
|
||||||
|
// if the setter is for a list, populate the values
|
||||||
|
if len(s.ListValues) > 0 {
|
||||||
|
v = strings.Join(s.ListValues, ",")
|
||||||
|
v = fmt.Sprintf("[%s]", v)
|
||||||
|
}
|
||||||
|
table.Append([]string{
|
||||||
|
s.Name, v, s.SetBy, s.Description, fmt.Sprintf("%d", s.Count)})
|
||||||
|
}
|
||||||
|
table.Render()
|
||||||
|
|
||||||
|
if len(r.List.Setters) == 0 {
|
||||||
|
// exit non-0 if no matching setters are found
|
||||||
|
if ExitOnError {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ListSettersRunner) ListSubstitutions(c *cobra.Command, args []string) error {
|
||||||
|
// use setters v2
|
||||||
|
path, err := ext.GetOpenAPIFile(args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := r.List.ListSubst(path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
table := newTable(c.OutOrStdout(), r.Markdown)
|
||||||
|
table.SetHeader([]string{"SUBSTITUTION", "PATTERN", "SETTERS"})
|
||||||
|
for i := range r.List.Substitutions {
|
||||||
|
s := r.List.Substitutions[i]
|
||||||
|
setters := ""
|
||||||
|
for _, value := range s.Values {
|
||||||
|
setter := strings.TrimPrefix(value.Ref, setters2.DefinitionsPrefix+setters2.SetterDefinitionPrefix)
|
||||||
|
setters = setters + "," + setter
|
||||||
|
}
|
||||||
|
setters = fmt.Sprintf("[%s]", strings.TrimPrefix(setters, ","))
|
||||||
|
table.Append([]string{
|
||||||
|
s.Name, s.Pattern, setters})
|
||||||
|
}
|
||||||
|
if len(r.List.Substitutions) == 0 {
|
||||||
|
// exit non-0 if no matching substitutions are found
|
||||||
|
if ExitOnError {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
table.Render()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func newTable(o io.Writer, m bool) *tablewriter.Table {
|
func newTable(o io.Writer, m bool) *tablewriter.Table {
|
||||||
table := tablewriter.NewWriter(o)
|
table := tablewriter.NewWriter(o)
|
||||||
table.SetRowLine(false)
|
table.SetRowLine(false)
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ spec:
|
|||||||
image nginx me2 hello world 2 2
|
image nginx me2 hello world 2 2
|
||||||
replicas 3 me1 hello world 1 1
|
replicas 3 me1 hello world 1 1
|
||||||
tag 1.7.9 me3 hello world 3 1
|
tag 1.7.9 me3 hello world 3 1
|
||||||
|
SUBSTITUTION PATTERN SETTERS
|
||||||
|
image IMAGE:TAG [image,tag]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -176,6 +178,8 @@ spec:
|
|||||||
image nginx me2 hello world 2 3
|
image nginx me2 hello world 2 3
|
||||||
replicas 3 me1 hello world 1 2
|
replicas 3 me1 hello world 1 2
|
||||||
tag 1.7.9 me3 hello world 3 2
|
tag 1.7.9 me3 hello world 3 2
|
||||||
|
SUBSTITUTION PATTERN SETTERS
|
||||||
|
image IMAGE:TAG [image,tag]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -247,6 +251,8 @@ spec:
|
|||||||
`,
|
`,
|
||||||
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
|
expected: ` NAME VALUE SET BY DESCRIPTION COUNT
|
||||||
image nginx me2 hello world 2 3
|
image nginx me2 hello world 2 3
|
||||||
|
SUBSTITUTION PATTERN SETTERS
|
||||||
|
image IMAGE:TAG [image,tag]
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ type List struct {
|
|||||||
Name string
|
Name string
|
||||||
|
|
||||||
Setters []SetterDefinition
|
Setters []SetterDefinition
|
||||||
|
|
||||||
|
Substitutions []SubstitutionDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
// List initializes l.Setters with the setters from the OpenAPI definitions in the file
|
// ListSetters initializes l.Setters with the setters from the OpenAPI definitions in the file
|
||||||
func (l *List) List(openAPIPath, resourcePath string) error {
|
func (l *List) ListSetters(openAPIPath, resourcePath string) error {
|
||||||
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
|
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -29,10 +31,22 @@ func (l *List) List(openAPIPath, resourcePath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return l.list(y, resourcePath)
|
return l.listSetters(y, resourcePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *List) list(object *yaml.RNode, resourcePath string) error {
|
// ListSubst initializes l.Substitutions with the substitutions from the OpenAPI definitions in the file
|
||||||
|
func (l *List) ListSubst(openAPIPath string) error {
|
||||||
|
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
y, err := yaml.ReadFile(openAPIPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return l.listSubst(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *List) listSetters(object *yaml.RNode, resourcePath string) error {
|
||||||
// read the OpenAPI definitions
|
// read the OpenAPI definitions
|
||||||
def, err := object.Pipe(yaml.LookupCreate(yaml.MappingNode, "openAPI", "definitions"))
|
def, err := object.Pipe(yaml.LookupCreate(yaml.MappingNode, "openAPI", "definitions"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,6 +119,66 @@ func (l *List) list(object *yaml.RNode, resourcePath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *List) listSubst(object *yaml.RNode) error {
|
||||||
|
// read the OpenAPI definitions
|
||||||
|
def, err := object.Pipe(yaml.LookupCreate(yaml.MappingNode, "openAPI", "definitions"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if yaml.IsEmpty(def) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate over definitions -- find those that are substitutions
|
||||||
|
err = def.VisitFields(func(node *yaml.MapNode) error {
|
||||||
|
subst := SubstitutionDefinition{}
|
||||||
|
|
||||||
|
// the definition key -- contains the substitution name
|
||||||
|
key := node.Key.YNode().Value
|
||||||
|
|
||||||
|
if !strings.HasPrefix(key, SubstitutionDefinitionPrefix) {
|
||||||
|
// not a substitution -- doesn't have the right prefix
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
substNode, err := node.Value.Pipe(yaml.Lookup(K8sCliExtensionKey, "substitution"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if yaml.IsEmpty(substNode) {
|
||||||
|
// has the substitution prefix, but missing the setter extension
|
||||||
|
return errors.Errorf("missing x-k8s-cli.substitution for %s", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshal the yaml for the substitution extension into the definition struct
|
||||||
|
b, err := substNode.String()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := yaml.Unmarshal([]byte(b), &subst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if l.Name != "" && l.Name != subst.Name {
|
||||||
|
// not the substitution that was requested by list
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Substitutions = append(l.Substitutions, subst)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the substitutions by their name
|
||||||
|
sort.Slice(l.Substitutions, func(i, j int) bool {
|
||||||
|
return l.Substitutions[i].Name < l.Substitutions[j].Name
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// count returns the number of fields set by the setter with name
|
// count returns the number of fields set by the setter with name
|
||||||
func (l *List) count(path, name string) (int, error) {
|
func (l *List) count(path, name string) (int, error) {
|
||||||
s := &Set{Name: name}
|
s := &Set{Name: name}
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ spec:
|
|||||||
|
|
||||||
// invoke the setter
|
// invoke the setter
|
||||||
instance := &List{Name: test.setter}
|
instance := &List{Name: test.setter}
|
||||||
err = instance.List(f.Name(), r.Name())
|
err = instance.ListSetters(f.Name(), r.Name())
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user