Fix names/doc in transformation config code.

This commit is contained in:
Jeffrey Regan
2018-10-10 17:29:50 -07:00
parent 111f41785f
commit d9f9a51e55
27 changed files with 475 additions and 305 deletions

View File

@@ -24,8 +24,6 @@ import (
"sigs.k8s.io/kustomize/pkg/transformers" "sigs.k8s.io/kustomize/pkg/transformers"
) )
// nameHashTransformer contains the prefix and the path config for each field that
// the name prefix will be applied.
type nameHashTransformer struct{} type nameHashTransformer struct{}
var _ transformers.Transformer = &nameHashTransformer{} var _ transformers.Transformer = &nameHashTransformer{}

View File

@@ -102,7 +102,7 @@ func (o *saveOptions) Complete(fsys fs.FileSystem) error {
// RunSave saves the default transformer configurations local directory // RunSave saves the default transformer configurations local directory
func (o *saveOptions) RunSave(fsys fs.FileSystem) error { func (o *saveOptions) RunSave(fsys fs.FileSystem) error {
m := defaultconfig.GetDefaultPathConfigStrings() m := defaultconfig.GetDefaultFieldSpecsAsMap()
for tname, tcfg := range m { for tname, tcfg := range m {
filename := filepath.Join(o.saveDirectory, tname+".yaml") filename := filepath.Join(o.saveDirectory, tname+".yaml")
err := fsys.WriteFile(filename, []byte(tcfg)) err := fsys.WriteFile(filename, []byte(tcfg))

View File

@@ -132,8 +132,8 @@ func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) {
if err != nil { if err != nil {
errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources")) errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources"))
} }
crdPathConfigs, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds) crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds)
kt.tcfg = kt.tcfg.Merge(crdPathConfigs) kt.tcfg = kt.tcfg.Merge(crdTc)
if err != nil { if err != nil {
errs.Append(errors.Wrap(err, "LoadCRDs")) errs.Append(errors.Wrap(err, "LoadCRDs"))
} }

View File

@@ -16,7 +16,7 @@ limitations under the License.
package defaultconfig package defaultconfig
const commonAnnotationPathConfigs = ` const commonAnnotationFieldSpecs = `
commonAnnotations: commonAnnotations:
- path: metadata/annotations - path: metadata/annotations
create: true create: true

View File

@@ -16,7 +16,7 @@ limitations under the License.
package defaultconfig package defaultconfig
const commonLabelPathConfigs = ` const commonLabelFieldSpecs = `
commonLabels: commonLabels:
- path: metadata/labels - path: metadata/labels
create: true create: true

View File

@@ -22,27 +22,28 @@ import (
"bytes" "bytes"
) )
// GetDefaultPathConfigs returns the default pathConfigs data // GetDefaultFieldSpecs returns default fieldSpecs.
func GetDefaultPathConfigs() []byte { func GetDefaultFieldSpecs() []byte {
configData := [][]byte{ configData := [][]byte{
[]byte(namePrefixPathConfigs), []byte(namePrefixFieldSpecs),
[]byte(commonLabelPathConfigs), []byte(commonLabelFieldSpecs),
[]byte(commonAnnotationPathConfigs), []byte(commonAnnotationFieldSpecs),
[]byte(namespacePathConfigs), []byte(namespaceFieldSpecs),
[]byte(varReferencePathConfigs), []byte(varReferenceFieldSpecs),
[]byte(nameReferencePathConfigs), []byte(nameReferenceFieldSpecs),
} }
return bytes.Join(configData, []byte("\n")) return bytes.Join(configData, []byte("\n"))
} }
// GetDefaultPathConfigStrings returns the default pathConfigs in string format // GetDefaultFieldSpecsAsMap returns default fieldSpecs
func GetDefaultPathConfigStrings() map[string]string { // as a string->string map.
func GetDefaultFieldSpecsAsMap() map[string]string {
result := make(map[string]string) result := make(map[string]string)
result["nameprefix"] = namePrefixPathConfigs result["nameprefix"] = namePrefixFieldSpecs
result["commonlabels"] = commonLabelPathConfigs result["commonlabels"] = commonLabelFieldSpecs
result["commonannotations"] = commonAnnotationPathConfigs result["commonannotations"] = commonAnnotationFieldSpecs
result["namespace"] = namespacePathConfigs result["namespace"] = namespaceFieldSpecs
result["varreference"] = varReferencePathConfigs result["varreference"] = varReferenceFieldSpecs
result["namereference"] = namespacePathConfigs result["namereference"] = nameReferenceFieldSpecs
return result return result
} }

View File

@@ -17,7 +17,7 @@ limitations under the License.
package defaultconfig package defaultconfig
const ( const (
namePrefixPathConfigs = ` namePrefixFieldSpecs = `
namePrefix: namePrefix:
- path: metadata/name - path: metadata/name
` `

View File

@@ -17,26 +17,26 @@ limitations under the License.
package defaultconfig package defaultconfig
const ( const (
nameReferencePathConfigs = ` nameReferenceFieldSpecs = `
nameReference: nameReference:
- kind: Deployment - kind: Deployment
pathConfigs: fieldSpecs:
- path: spec/scaleTargetRef/name - path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler kind: HorizontalPodAutoscaler
- kind: ReplicationController - kind: ReplicationController
pathConfigs: fieldSpecs:
- path: spec/scaleTargetRef/name - path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler kind: HorizontalPodAutoscaler
- kind: ReplicaSet - kind: ReplicaSet
pathConfigs: fieldSpecs:
- path: spec/scaleTargetRef/name - path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler kind: HorizontalPodAutoscaler
- kind: ConfigMap - kind: ConfigMap
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: spec/volumes/configMap/name - path: spec/volumes/configMap/name
version: v1 version: v1
kind: Pod kind: Pod
@@ -119,7 +119,7 @@ nameReference:
- kind: Secret - kind: Secret
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: spec/volumes/secret/secretName - path: spec/volumes/secret/secretName
version: v1 version: v1
kind: Pod kind: Pod
@@ -229,7 +229,7 @@ nameReference:
- kind: Service - kind: Service
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: spec/serviceName - path: spec/serviceName
kind: StatefulSet kind: StatefulSet
group: apps group: apps
@@ -240,14 +240,14 @@ nameReference:
- kind: Role - kind: Role
group: rbac.authorization.k8s.io group: rbac.authorization.k8s.io
pathConfigs: fieldSpecs:
- path: roleRef/name - path: roleRef/name
kind: RoleBinding kind: RoleBinding
group: rbac.authorization.k8s.io group: rbac.authorization.k8s.io
- kind: ClusterRole - kind: ClusterRole
group: rbac.authorization.k8s.io group: rbac.authorization.k8s.io
pathConfigs: fieldSpecs:
- path: roleRef/name - path: roleRef/name
kind: RoleBinding kind: RoleBinding
group: rbac.authorization.k8s.io group: rbac.authorization.k8s.io
@@ -257,7 +257,7 @@ nameReference:
- kind: ServiceAccount - kind: ServiceAccount
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: subjects/name - path: subjects/name
kind: RoleBinding kind: RoleBinding
group: rbac.authorization.k8s.io group: rbac.authorization.k8s.io
@@ -281,7 +281,7 @@ nameReference:
- kind: PersistentVolumeClaim - kind: PersistentVolumeClaim
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: spec/volumes/persistentVolumeClaim/claimName - path: spec/volumes/persistentVolumeClaim/claimName
kind: Pod kind: Pod
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName - path: spec/template/spec/volumes/persistentVolumeClaim/claimName
@@ -299,7 +299,7 @@ nameReference:
- kind: PersistentVolume - kind: PersistentVolume
version: v1 version: v1
pathConfigs: fieldSpecs:
- path: spec/volumeName - path: spec/volumeName
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
` `

View File

@@ -17,7 +17,7 @@ limitations under the License.
package defaultconfig package defaultconfig
const ( const (
namespacePathConfigs = ` namespaceFieldSpecs = `
namespace: namespace:
- path: metadata/namespace - path: metadata/namespace
create: true create: true

View File

@@ -17,7 +17,7 @@ limitations under the License.
package defaultconfig package defaultconfig
const ( const (
varReferencePathConfigs = ` varReferenceFieldSpecs = `
varReference: varReference:
- path: spec/template/spec/initContainers/command - path: spec/template/spec/initContainers/command
kind: StatefulSet kind: StatefulSet

View File

@@ -78,7 +78,7 @@ func (tf *Factory) EmptyConfig() *TransformerConfig {
// This should never fail, hence the Fatal panic. // This should never fail, hence the Fatal panic.
func (tf *Factory) DefaultConfig() *TransformerConfig { func (tf *Factory) DefaultConfig() *TransformerConfig {
c, err := makeTransformerConfigFromBytes( c, err := makeTransformerConfigFromBytes(
defaultconfig.GetDefaultPathConfigs()) defaultconfig.GetDefaultFieldSpecs())
if err != nil { if err != nil {
log.Fatalf("Unable to make default transformconfig: %v", err) log.Fatalf("Unable to make default transformconfig: %v", err)
} }

View File

@@ -41,7 +41,7 @@ namePrefix:
fakeFS.WriteFile("transformerconfig/test/config.yaml", []byte(transformerConfig)) fakeFS.WriteFile("transformerconfig/test/config.yaml", []byte(transformerConfig))
ldr := loader.NewFileLoader(fakeFS) ldr := loader.NewFileLoader(fakeFS)
expected := &TransformerConfig{ expected := &TransformerConfig{
NamePrefix: []PathConfig{ NamePrefix: []FieldSpec{
{ {
Gvk: gvk.Gvk{Kind: "SomeKind"}, Gvk: gvk.Gvk{Kind: "SomeKind"},
Path: "nameprefix/path", Path: "nameprefix/path",

View File

@@ -27,15 +27,15 @@ import (
// LoadCRDs parse CRD schemas from paths into a TransformerConfig // LoadCRDs parse CRD schemas from paths into a TransformerConfig
func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) { func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) {
pathConfigs := tf.EmptyConfig() tc := tf.EmptyConfig()
for _, path := range paths { for _, path := range paths {
pathConfig, err := tf.loadCRD(path) otherTc, err := tf.loadCRD(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
pathConfigs = pathConfigs.Merge(pathConfig) tc = tc.Merge(otherTc)
} }
return pathConfigs, nil return tc, nil
} }
func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) { func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) {
@@ -57,13 +57,13 @@ func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) {
crds := getCRDs(types) crds := getCRDs(types)
for crd, k := range crds { for crd, k := range crds {
crdPathConfigs := tf.EmptyConfig() tc := tf.EmptyConfig()
err = getCRDPathConfig( err = loadCrdIntoConfig(
types, crd, crd, k, []string{}, crdPathConfigs) types, crd, crd, k, []string{}, tc)
if err != nil { if err != nil {
return result, err return result, err
} }
result = result.Merge(crdPathConfigs) result = result.Merge(tc)
} }
return result, nil return result, nil
@@ -88,10 +88,11 @@ func getCRDs(types map[string]common.OpenAPIDefinition) map[string]gvk.Gvk {
return crds return crds
} }
// getCRDPathConfig gets pathConfigs for one CRD recursively // loadCrdIntoConfig loads a CRD spec into a TransformerConfig
func getCRDPathConfig( func loadCrdIntoConfig(
types map[string]common.OpenAPIDefinition, atype string, crd string, in gvk.Gvk, types map[string]common.OpenAPIDefinition,
path []string, configs *TransformerConfig) error { atype string, crd string, in gvk.Gvk,
path []string, config *TransformerConfig) error {
if _, ok := types[crd]; !ok { if _, ok := types[crd]; !ok {
return nil return nil
} }
@@ -99,8 +100,8 @@ func getCRDPathConfig(
for propname, property := range types[atype].Schema.SchemaProps.Properties { for propname, property := range types[atype].Schema.SchemaProps.Properties {
_, annotate := property.Extensions.GetString(Annotation) _, annotate := property.Extensions.GetString(Annotation)
if annotate { if annotate {
configs.AddAnnotationPathConfig( config.AddAnnotationFieldSpec(
PathConfig{ FieldSpec{
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: in, Gvk: in,
Path: strings.Join(append(path, propname), "/"), Path: strings.Join(append(path, propname), "/"),
@@ -109,8 +110,8 @@ func getCRDPathConfig(
} }
_, label := property.Extensions.GetString(LabelSelector) _, label := property.Extensions.GetString(LabelSelector)
if label { if label {
configs.AddLabelPathConfig( config.AddLabelFieldSpec(
PathConfig{ FieldSpec{
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: in, Gvk: in,
Path: strings.Join(append(path, propname), "/"), Path: strings.Join(append(path, propname), "/"),
@@ -119,8 +120,8 @@ func getCRDPathConfig(
} }
_, identity := property.Extensions.GetString(Identity) _, identity := property.Extensions.GetString(Identity)
if identity { if identity {
configs.AddPrefixPathConfig( config.AddPrefixFieldSpec(
PathConfig{ FieldSpec{
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: in, Gvk: in,
Path: strings.Join(append(path, propname), "/"), Path: strings.Join(append(path, propname), "/"),
@@ -135,9 +136,9 @@ func getCRDPathConfig(
if !ok { if !ok {
nameKey = "name" nameKey = "name"
} }
configs.AddNamereferencePathConfig(ReferencePathConfig{ config.AddNamereferenceFieldSpec(NameBackReferences{
Gvk: gvk.Gvk{Kind: kind, Version: version}, Gvk: gvk.Gvk{Kind: kind, Version: version},
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: in, Gvk: in,
@@ -149,7 +150,9 @@ func getCRDPathConfig(
} }
if property.Ref.GetURL() != nil { if property.Ref.GetURL() != nil {
getCRDPathConfig(types, property.Ref.String(), crd, in, append(path, propname), configs) loadCrdIntoConfig(
types, property.Ref.String(), crd, in,
append(path, propname), config)
} }
} }
return nil return nil

View File

@@ -25,6 +25,12 @@ import (
"sigs.k8s.io/kustomize/pkg/internal/loadertest" "sigs.k8s.io/kustomize/pkg/internal/loadertest"
) )
// This defines two CRD's: Bee and MyKind.
//
// Bee is boring, it's spec has no dependencies.
//
// MyKind, however, has a spec that contains
// a Bee and a (k8s native) Secret.
const ( const (
crdContent = ` crdContent = `
{ {
@@ -149,10 +155,10 @@ func makeLoader(t *testing.T) ifc.Loader {
} }
func TestLoadCRDs(t *testing.T) { func TestLoadCRDs(t *testing.T) {
refpathconfigs := []ReferencePathConfig{ nbrs := []NameBackReferences{
{ {
Gvk: gvk.Gvk{Kind: "Secret", Version: "v1"}, Gvk: gvk.Gvk{Kind: "Secret", Version: "v1"},
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: gvk.Gvk{Kind: "MyKind"}, Gvk: gvk.Gvk{Kind: "MyKind"},
@@ -162,7 +168,7 @@ func TestLoadCRDs(t *testing.T) {
}, },
{ {
Gvk: gvk.Gvk{Kind: "Bee", Version: "v1beta1"}, Gvk: gvk.Gvk{Kind: "Bee", Version: "v1beta1"},
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
CreateIfNotPresent: false, CreateIfNotPresent: false,
Gvk: gvk.Gvk{Kind: "MyKind"}, Gvk: gvk.Gvk{Kind: "MyKind"},
@@ -172,14 +178,14 @@ func TestLoadCRDs(t *testing.T) {
}, },
} }
expected := &TransformerConfig{ expectedTc := &TransformerConfig{
NameReference: refpathconfigs, NameReference: nbrs,
} }
pathconfig, _ := NewFactory(makeLoader(t)).LoadCRDs( actualTc, _ := NewFactory(makeLoader(t)).LoadCRDs(
[]string{"/testpath/crd.json"}) []string{"/testpath/crd.json"})
if !reflect.DeepEqual(pathconfig, expected) { if !reflect.DeepEqual(actualTc, expectedTc) {
t.Fatalf("expected\n %v\n but got\n %v\n", expected, pathconfig) t.Fatalf("expected\n %v\n but got\n %v\n", expectedTc, actualTc)
} }
} }

View File

@@ -0,0 +1,87 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/pkg/gvk"
)
// FieldSpec completely specifies a kustomizable field in
// an unstructured representation of a k8s API object.
// It helps define the operands of transformations.
//
// For example, a directive to add a common label to objects
// will need to know that a 'Deployment' object (in API group
// 'apps', any version) can have labels at field path
// 'spec/template/metadata/labels', and further that it is OK
// (or not OK) to add that field path to the object if the
// field path doesn't exist already.
//
// This would look like
// {
// group: apps
// kind: Deployment
// path: spec/template/metadata/labels
// create: true
// }
type FieldSpec struct {
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
CreateIfNotPresent bool `json:"create,omitempty" yaml:"create,omitempty"`
}
const (
escapedForwardSlash = "\\/"
tempSlashReplacement = "???"
)
func (fs FieldSpec) String() string {
return fmt.Sprintf(
"%s:%v:%s", fs.Gvk.String(), fs.CreateIfNotPresent, fs.Path)
}
// PathSlice converts the path string to a slice of strings,
// separated by a '/'. Forward slash can be contained in a
// fieldname. such as ingress.kubernetes.io/auth-secret in
// Ingress annotations. To deal with this special case, the
// path to this field should be formatted as
//
// metadata/annotations/ingress.kubernetes.io\/auth-secret
//
// Then PathSlice will return
//
// []string{
// "metadata",
// "annotations",
// "ingress.auth-secretkubernetes.io/auth-secret"
// }
func (fs FieldSpec) PathSlice() []string {
if !strings.Contains(fs.Path, escapedForwardSlash) {
return strings.Split(fs.Path, "/")
}
s := strings.Replace(fs.Path, escapedForwardSlash, tempSlashReplacement, -1)
paths := strings.Split(s, "/")
var result []string
for _, path := range paths {
result = append(result, strings.Replace(path, tempSlashReplacement, "/", -1))
}
return result
}

View File

@@ -37,8 +37,8 @@ func TestPathSlice(t *testing.T) {
}, },
} }
for _, p := range paths { for _, p := range paths {
pathConfig := PathConfig{Path: p.input} fs := FieldSpec{Path: p.input}
actual := pathConfig.PathSlice() actual := fs.PathSlice()
if !reflect.DeepEqual(actual, p.parsed) { if !reflect.DeepEqual(actual, p.parsed) {
t.Fatalf("expected %v, but got %v", p.parsed, actual) t.Fatalf("expected %v, but got %v", p.parsed, actual)
} }

View File

@@ -0,0 +1,91 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"sigs.k8s.io/kustomize/pkg/gvk"
"strings"
)
// NameBackReferences is an association between a gvk.GVK and a list
// of FieldSpec instances that could refer to it.
//
// It is used to handle name changes, and can be thought of as a
// a contact list. If you change your own contact info (name,
// phone number, etc.), you must tell your contacts or they won't
// know about the change.
//
// For example, ConfigMaps can be used by Pods and everything that
// contains a Pod; Deployment, Job, StatefulSet, etc. To change
// the name of a ConfigMap instance from 'alice' to 'bob', one
// must visit all objects that could refer to the ConfigMap, see if
// they mention 'alice', and if so, change the reference to 'bob'.
//
// The NameBackReferences instance to aid in this could look like
// {
// kind: ConfigMap
// version: v1
// FieldSpecs:
// - kind: Pod
// version: v1
// path: spec/volumes/configMap/name
// - kind: Deployment
// path: spec/template/spec/volumes/configMap/name
// - kind: Job
// path: spec/template/spec/volumes/configMap/name
// (etc.)
// }
type NameBackReferences struct {
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
FieldSpecs []FieldSpec `json:"FieldSpecs,omitempty" yaml:"FieldSpecs,omitempty"`
}
func (n NameBackReferences) String() string {
var r []string
for _, f := range n.FieldSpecs {
r = append(r, f.String())
}
return n.Gvk.String() + ": (\n" +
strings.Join(r, "\n") + "\n)"
}
func mergeNameBackReferences(
a, b []NameBackReferences) []NameBackReferences {
for _, r := range b {
a = merge(a, r)
}
return a
}
func merge(
backRefsSlice []NameBackReferences,
other NameBackReferences) []NameBackReferences {
var result []NameBackReferences
found := false
for _, c := range backRefsSlice {
if c.Equals(other.Gvk) {
c.FieldSpecs = append(c.FieldSpecs, other.FieldSpecs...)
found = true
}
result = append(result, c)
}
if !found {
result = append(result, other)
}
return result
}

View File

@@ -0,0 +1,106 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"reflect"
"sigs.k8s.io/kustomize/pkg/gvk"
"testing"
)
func TestFoo(t *testing.T) {
fsSlice1 := []FieldSpec{
{
Gvk: gvk.Gvk{
Kind: "Pod",
},
Path: "path/to/a/name",
CreateIfNotPresent: false,
},
{
Gvk: gvk.Gvk{
Kind: "Deployment",
},
Path: "another/path/to/some/name",
CreateIfNotPresent: false,
},
}
fsSlice2 := []FieldSpec{
{
Gvk: gvk.Gvk{
Kind: "Job",
},
Path: "morepath/to/name",
CreateIfNotPresent: false,
},
{
Gvk: gvk.Gvk{
Kind: "StatefulSet",
},
Path: "yet/another/path/to/a/name",
CreateIfNotPresent: false,
},
}
nbrsSlice1 := []NameBackReferences{
{
Gvk: gvk.Gvk{
Kind: "ConfigMap",
},
FieldSpecs: fsSlice1,
},
{
Gvk: gvk.Gvk{
Kind: "Secret",
},
FieldSpecs: fsSlice2,
},
}
nbrsSlice2 := []NameBackReferences{
{
Gvk: gvk.Gvk{
Kind: "ConfigMap",
},
FieldSpecs: fsSlice1,
},
{
Gvk: gvk.Gvk{
Kind: "Secret",
},
FieldSpecs: fsSlice2,
},
}
expected := []NameBackReferences{
{
Gvk: gvk.Gvk{
Kind: "ConfigMap",
},
// Current behavior allows repeats of FieldSpec
FieldSpecs: append(fsSlice1, fsSlice1...),
},
{
Gvk: gvk.Gvk{
Kind: "Secret",
},
FieldSpecs: append(fsSlice2, fsSlice2...),
},
}
actual := mergeNameBackReferences(nbrsSlice1, nbrsSlice2)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected\n %v\n but got\n %v\n", expected, actual)
}
}

View File

@@ -1,60 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"strings"
"sigs.k8s.io/kustomize/pkg/gvk"
)
// PathConfig contains the configuration of a field, including the gvk it ties to,
// path to the field, etc.
type PathConfig struct {
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
CreateIfNotPresent bool `json:"create,omitempty" yaml:"create,omitempty"`
}
const (
escapedForwardSlash = "\\/"
tempSlashReplacement = "???"
)
// PathSlice converts the path string to a slice of strings, separated by "/"
// "/" can be contained in a fieldname.
// such as ingress.kubernetes.io/auth-secret in Ingress annotations.
// To deal with this special case, the path to this field should be formatted as
//
// metadata/annotations/ingress.kubernetes.io\/auth-secret
//
// Then PathSlice will return
//
// []string{"metadata", "annotations", "ingress.auth-secretkubernetes.io/auth-secret"}
func (p PathConfig) PathSlice() []string {
if !strings.Contains(p.Path, escapedForwardSlash) {
return strings.Split(p.Path, "/")
}
s := strings.Replace(p.Path, escapedForwardSlash, tempSlashReplacement, -1)
paths := strings.Split(s, "/")
var result []string
for _, path := range paths {
result = append(result, strings.Replace(path, tempSlashReplacement, "/", -1))
}
return result
}

View File

@@ -1,64 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"sigs.k8s.io/kustomize/pkg/gvk"
)
// ReferencePathConfig contains the configuration of a field that references
// the name of another resource whose GroupVersionKind is specified in referencedGVK.
// e.g. pod.spec.template.volumes.configMap.name references the name of a configmap
// Its corresponding referencePathConfig will look like:
//
// ReferencePathConfig{
// referencedGVK: schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"},
// pathConfigs: []PathConfig{
// {
// GroupVersionKind: &schema.GroupVersionKind{Version: "v1", Kind: "Pod"},
// Path: []string{"spec", "volumes", "configMap", "name"},
// },
// }
type ReferencePathConfig struct {
gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
// PathConfig is the gvk that is referencing the referencedGVK object's name.
PathConfigs []PathConfig `json:"pathConfigs,omitempty" yaml:"pathConfigs,omitempty"`
}
func merge(configs []ReferencePathConfig, config ReferencePathConfig) []ReferencePathConfig {
var result []ReferencePathConfig
found := false
for _, c := range configs {
if c.Equals(config.Gvk) {
c.PathConfigs = append(c.PathConfigs, config.PathConfigs...)
found = true
}
result = append(result, c)
}
if !found {
result = append(result, config)
}
return result
}
func mergeNameReferencePathConfigs(a, b []ReferencePathConfig) []ReferencePathConfig {
for _, r := range b {
a = merge(a, r)
}
return a
}

View File

@@ -22,30 +22,30 @@ import (
"sort" "sort"
) )
type rpcSlice []ReferencePathConfig type nbrSlice []NameBackReferences
func (s rpcSlice) Len() int { return len(s) } func (s nbrSlice) Len() int { return len(s) }
func (s rpcSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s nbrSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s rpcSlice) Less(i, j int) bool { func (s nbrSlice) Less(i, j int) bool {
return s[i].Gvk.IsLessThan(s[j].Gvk) return s[i].Gvk.IsLessThan(s[j].Gvk)
} }
type pcSlice []PathConfig type fsSlice []FieldSpec
func (s pcSlice) Len() int { return len(s) } func (s fsSlice) Len() int { return len(s) }
func (s pcSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s fsSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s pcSlice) Less(i, j int) bool { func (s fsSlice) Less(i, j int) bool {
return s[i].Gvk.IsLessThan(s[j].Gvk) return s[i].Gvk.IsLessThan(s[j].Gvk)
} }
// TransformerConfig represents the path configurations for different transformations // TransformerConfig holds the data needed to perform transformations.
type TransformerConfig struct { type TransformerConfig struct {
NamePrefix pcSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"` NamePrefix fsSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
NameSpace pcSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"` NameSpace fsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
CommonLabels pcSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"` CommonLabels fsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
CommonAnnotations pcSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"` CommonAnnotations fsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
NameReference rpcSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"` NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
VarReference pcSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"` VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
} }
// sortFields provides determinism in logging, tests, etc. // sortFields provides determinism in logging, tests, etc.
@@ -58,24 +58,24 @@ func (t *TransformerConfig) sortFields() {
sort.Sort(t.VarReference) sort.Sort(t.VarReference)
} }
// AddPrefixPathConfig adds a PathConfig to NamePrefix // AddPrefixFieldSpec adds a FieldSpec to NamePrefix
func (t *TransformerConfig) AddPrefixPathConfig(config PathConfig) { func (t *TransformerConfig) AddPrefixFieldSpec(fs FieldSpec) {
t.NamePrefix = append(t.NamePrefix, config) t.NamePrefix = append(t.NamePrefix, fs)
} }
// AddLabelPathConfig adds a PathConfig to CommonLabels // AddLabelFieldSpec adds a FieldSpec to CommonLabels
func (t *TransformerConfig) AddLabelPathConfig(config PathConfig) { func (t *TransformerConfig) AddLabelFieldSpec(fs FieldSpec) {
t.CommonLabels = append(t.CommonLabels, config) t.CommonLabels = append(t.CommonLabels, fs)
} }
// AddAnnotationPathConfig adds a PathConfig to CommonAnnotations // AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
func (t *TransformerConfig) AddAnnotationPathConfig(config PathConfig) { func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) {
t.CommonAnnotations = append(t.CommonAnnotations, config) t.CommonAnnotations = append(t.CommonAnnotations, fs)
} }
// AddNamereferencePathConfig adds a ReferencePathConfig to NameReference // AddNamereferenceFieldSpec adds a NameBackReferences to NameReference
func (t *TransformerConfig) AddNamereferencePathConfig(config ReferencePathConfig) { func (t *TransformerConfig) AddNamereferenceFieldSpec(nbrs NameBackReferences) {
t.NameReference = mergeNameReferencePathConfigs(t.NameReference, []ReferencePathConfig{config}) t.NameReference = mergeNameBackReferences(t.NameReference, []NameBackReferences{nbrs})
} }
// Merge merges two TransformerConfigs objects into a new TransformerConfig object // Merge merges two TransformerConfigs objects into a new TransformerConfig object
@@ -86,7 +86,7 @@ func (t *TransformerConfig) Merge(input *TransformerConfig) *TransformerConfig {
merged.CommonAnnotations = append(t.CommonAnnotations, input.CommonAnnotations...) merged.CommonAnnotations = append(t.CommonAnnotations, input.CommonAnnotations...)
merged.CommonLabels = append(t.CommonLabels, input.CommonLabels...) merged.CommonLabels = append(t.CommonLabels, input.CommonLabels...)
merged.VarReference = append(t.VarReference, input.VarReference...) merged.VarReference = append(t.VarReference, input.VarReference...)
merged.NameReference = mergeNameReferencePathConfigs(t.NameReference, input.NameReference) merged.NameReference = mergeNameBackReferences(t.NameReference, input.NameReference)
merged.sortFields() merged.sortFields()
return merged return merged
} }

View File

@@ -24,14 +24,14 @@ import (
"sigs.k8s.io/kustomize/pkg/gvk" "sigs.k8s.io/kustomize/pkg/gvk"
) )
func TestAddNameReferencePathConfigs(t *testing.T) { func TestAddNamereferenceFieldSpec(t *testing.T) {
cfg := &TransformerConfig{} cfg := &TransformerConfig{}
pathConfig := ReferencePathConfig{ nbrs := NameBackReferences{
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindA", Kind: "KindA",
}, },
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindB", Kind: "KindB",
@@ -42,42 +42,42 @@ func TestAddNameReferencePathConfigs(t *testing.T) {
}, },
} }
cfg.AddNamereferencePathConfig(pathConfig) cfg.AddNamereferenceFieldSpec(nbrs)
if len(cfg.NameReference) != 1 { if len(cfg.NameReference) != 1 {
t.Fatal("failed to add namerefence pathconfig") t.Fatal("failed to add namerefence FieldSpec")
} }
} }
func TestAddPathConfigs(t *testing.T) { func TestAddFieldSpecs(t *testing.T) {
cfg := &TransformerConfig{} cfg := &TransformerConfig{}
pathConfig := PathConfig{ fieldSpec := FieldSpec{
Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"}, Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"},
Path: "path/to/a/field", Path: "path/to/a/field",
CreateIfNotPresent: true, CreateIfNotPresent: true,
} }
cfg.AddPrefixPathConfig(pathConfig) cfg.AddPrefixFieldSpec(fieldSpec)
if len(cfg.NamePrefix) != 1 { if len(cfg.NamePrefix) != 1 {
t.Fatalf("failed to add nameprefix pathconfig") t.Fatalf("failed to add nameprefix FieldSpec")
} }
cfg.AddLabelPathConfig(pathConfig) cfg.AddLabelFieldSpec(fieldSpec)
if len(cfg.CommonLabels) != 1 { if len(cfg.CommonLabels) != 1 {
t.Fatalf("failed to add nameprefix pathconfig") t.Fatalf("failed to add nameprefix FieldSpec")
} }
cfg.AddAnnotationPathConfig(pathConfig) cfg.AddAnnotationFieldSpec(fieldSpec)
if len(cfg.CommonAnnotations) != 1 { if len(cfg.CommonAnnotations) != 1 {
t.Fatalf("failed to add nameprefix pathconfig") t.Fatalf("failed to add nameprefix FieldSpec")
} }
} }
func TestMerge(t *testing.T) { func TestMerge(t *testing.T) {
nameReference := []ReferencePathConfig{ nameReference := []NameBackReferences{
{ {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindA", Kind: "KindA",
}, },
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindB", Kind: "KindB",
@@ -91,7 +91,7 @@ func TestMerge(t *testing.T) {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindA", Kind: "KindA",
}, },
PathConfigs: []PathConfig{ FieldSpecs: []FieldSpec{
{ {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "KindC", Kind: "KindC",
@@ -102,7 +102,7 @@ func TestMerge(t *testing.T) {
}, },
}, },
} }
pathConfigs := []PathConfig{ fieldSpecs := []FieldSpec{
{ {
Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"}, Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"},
Path: "path/to/a/field", Path: "path/to/a/field",
@@ -115,28 +115,28 @@ func TestMerge(t *testing.T) {
}, },
} }
cfga := &TransformerConfig{} cfga := &TransformerConfig{}
cfga.AddNamereferencePathConfig(nameReference[0]) cfga.AddNamereferenceFieldSpec(nameReference[0])
cfga.AddPrefixPathConfig(pathConfigs[0]) cfga.AddPrefixFieldSpec(fieldSpecs[0])
cfgb := &TransformerConfig{} cfgb := &TransformerConfig{}
cfgb.AddNamereferencePathConfig(nameReference[1]) cfgb.AddNamereferenceFieldSpec(nameReference[1])
cfgb.AddPrefixPathConfig(pathConfigs[1]) cfgb.AddPrefixFieldSpec(fieldSpecs[1])
actual := cfga.Merge(cfgb) actual := cfga.Merge(cfgb)
if len(actual.NamePrefix) != 2 { if len(actual.NamePrefix) != 2 {
t.Fatal("merge failed for namePrefix pathconfig") t.Fatal("merge failed for namePrefix FieldSpec")
} }
if len(actual.NameReference) != 1 { if len(actual.NameReference) != 1 {
t.Fatal("merge failed for namereference pathconfig") t.Fatal("merge failed for namereference FieldSpec")
} }
expected := &TransformerConfig{} expected := &TransformerConfig{}
expected.AddNamereferencePathConfig(nameReference[0]) expected.AddNamereferenceFieldSpec(nameReference[0])
expected.AddNamereferencePathConfig(nameReference[1]) expected.AddNamereferenceFieldSpec(nameReference[1])
expected.AddPrefixPathConfig(pathConfigs[0]) expected.AddPrefixFieldSpec(fieldSpecs[0])
expected.AddPrefixPathConfig(pathConfigs[1]) expected.AddPrefixFieldSpec(fieldSpecs[1])
if !reflect.DeepEqual(actual, expected) { if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected: %v\n but got: %v\n", expected, actual) t.Fatalf("expected: %v\n but got: %v\n", expected, actual)

View File

@@ -24,34 +24,36 @@ import (
"sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/transformers/config"
) )
// mapTransformer contains a map string->string and path configs // mapTransformer applies a string->string map to fieldSpecs.
// The map will be applied to the fields specified in path configs.
type mapTransformer struct { type mapTransformer struct {
m map[string]string m map[string]string
pathConfigs []config.PathConfig fieldSpecs []config.FieldSpec
} }
var _ Transformer = &mapTransformer{} var _ Transformer = &mapTransformer{}
// NewLabelsMapTransformer construct a mapTransformer with a given pathConfig slice // NewLabelsMapTransformer constructs a mapTransformer.
func NewLabelsMapTransformer(m map[string]string, p []config.PathConfig) (Transformer, error) { func NewLabelsMapTransformer(
return NewMapTransformer(p, m) m map[string]string, fs []config.FieldSpec) (Transformer, error) {
return NewMapTransformer(fs, m)
} }
// NewAnnotationsMapTransformer construct a mapTransformer with a given pathConfig slice // NewAnnotationsMapTransformer construct a mapTransformer.
func NewAnnotationsMapTransformer(m map[string]string, p []config.PathConfig) (Transformer, error) { func NewAnnotationsMapTransformer(
return NewMapTransformer(p, m) m map[string]string, fs []config.FieldSpec) (Transformer, error) {
return NewMapTransformer(fs, m)
} }
// NewMapTransformer construct a mapTransformer. // NewMapTransformer construct a mapTransformer.
func NewMapTransformer(pc []config.PathConfig, m map[string]string) (Transformer, error) { func NewMapTransformer(
pc []config.FieldSpec, m map[string]string) (Transformer, error) {
if m == nil { if m == nil {
return NewNoOpTransformer(), nil return NewNoOpTransformer(), nil
} }
if pc == nil { if pc == nil {
return nil, errors.New("pathConfigs is not expected to be nil") return nil, errors.New("fieldSpecs is not expected to be nil")
} }
return &mapTransformer{pathConfigs: pc, m: m}, nil return &mapTransformer{fieldSpecs: pc, m: m}, nil
} }
// Transform apply each <key, value> pair in the mapTransformer to the // Transform apply each <key, value> pair in the mapTransformer to the
@@ -59,7 +61,7 @@ func NewMapTransformer(pc []config.PathConfig, m map[string]string) (Transformer
func (o *mapTransformer) Transform(m resmap.ResMap) error { func (o *mapTransformer) Transform(m resmap.ResMap) error {
for id := range m { for id := range m {
objMap := m[id].Map() objMap := m[id].Map()
for _, path := range o.pathConfigs { for _, path := range o.fieldSpecs {
if !id.Gvk().IsSelected(&path.Gvk) { if !id.Gvk().IsSelected(&path.Gvk) {
continue continue
} }

View File

@@ -26,36 +26,36 @@ import (
"sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/transformers/config"
) )
// nameReferenceTransformer contains the referencing info between 2 GroupVersionKinds
type nameReferenceTransformer struct { type nameReferenceTransformer struct {
pathConfigs []config.ReferencePathConfig backRefs []config.NameBackReferences
} }
var _ Transformer = &nameReferenceTransformer{} var _ Transformer = &nameReferenceTransformer{}
// NewNameReferenceTransformer constructs a nameReferenceTransformer // NewNameReferenceTransformer constructs a nameReferenceTransformer
// with a given Reference PathConfig slice // with a given slice of NameBackReferences.
func NewNameReferenceTransformer(pc []config.ReferencePathConfig) (Transformer, error) { func NewNameReferenceTransformer(
if pc == nil { br []config.NameBackReferences) (Transformer, error) {
return nil, errors.New("pathConfigs is not expected to be nil") if br == nil {
return nil, errors.New("backrefs not expected to be nil")
} }
return &nameReferenceTransformer{pathConfigs: pc}, nil return &nameReferenceTransformer{backRefs: br}, nil
} }
// Transform does the fields update according to pathConfigs. // Transform does the fields update according to fieldSpecs.
// The old name is in the key in the map and the new name is in the object // The old name is in the key in the map and the new name is in the object
// associated with the key. e.g. if <k, v> is one of the key-value pair in the map, // associated with the key. e.g. if <k, v> is one of the key-value pair in the map,
// then the old name is k.Name and the new name is v.GetName() // then the old name is k.Name and the new name is v.GetName()
func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error { func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error {
for id := range m { for id := range m {
objMap := m[id].Map() objMap := m[id].Map()
for _, referencePathConfig := range o.pathConfigs { for _, backRef := range o.backRefs {
for _, path := range referencePathConfig.PathConfigs { for _, path := range backRef.FieldSpecs {
if !id.Gvk().IsSelected(&path.Gvk) { if !id.Gvk().IsSelected(&path.Gvk) {
continue continue
} }
err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent, err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent,
o.updateNameReference(referencePathConfig.Gvk, m.FilterBy(id))) o.updateNameReference(backRef.Gvk, m.FilterBy(id)))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -23,12 +23,12 @@ import (
) )
type namespaceTransformer struct { type namespaceTransformer struct {
namespace string namespace string
pathConfigs []config.PathConfig fieldSpecsToUse []config.FieldSpec
skipPathConfigs []config.PathConfig fieldSpecsToSkip []config.FieldSpec
} }
var skipNamespacePathConfigs = []config.PathConfig{ var namespaceFieldSpecsToSkip = []config.FieldSpec{
{ {
Gvk: gvk.Gvk{ Gvk: gvk.Gvk{
Kind: "Namespace", Kind: "Namespace",
@@ -54,15 +54,15 @@ var skipNamespacePathConfigs = []config.PathConfig{
var _ Transformer = &namespaceTransformer{} var _ Transformer = &namespaceTransformer{}
// NewNamespaceTransformer construct a namespaceTransformer. // NewNamespaceTransformer construct a namespaceTransformer.
func NewNamespaceTransformer(ns string, cf []config.PathConfig) Transformer { func NewNamespaceTransformer(ns string, cf []config.FieldSpec) Transformer {
if len(ns) == 0 { if len(ns) == 0 {
return NewNoOpTransformer() return NewNoOpTransformer()
} }
return &namespaceTransformer{ return &namespaceTransformer{
namespace: ns, namespace: ns,
pathConfigs: cf, fieldSpecsToUse: cf,
skipPathConfigs: skipNamespacePathConfigs, fieldSpecsToSkip: namespaceFieldSpecsToSkip,
} }
} }
@@ -72,7 +72,7 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
for id := range m { for id := range m {
found := false found := false
for _, path := range o.skipPathConfigs { for _, path := range o.fieldSpecsToSkip {
if id.Gvk().IsSelected(&path.Gvk) { if id.Gvk().IsSelected(&path.Gvk) {
found = true found = true
break break
@@ -86,7 +86,7 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
for id := range mf { for id := range mf {
objMap := mf[id].Map() objMap := mf[id].Map()
for _, path := range o.pathConfigs { for _, path := range o.fieldSpecsToUse {
if !id.Gvk().IsSelected(&path.Gvk) { if !id.Gvk().IsSelected(&path.Gvk) {
continue continue
} }

View File

@@ -26,36 +26,36 @@ import (
"sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/transformers/config"
) )
// namePrefixTransformer contains the prefix and the path config for each field that // namePrefixTransformer contains the prefix and the FieldSpecs
// the name prefix will be applied. // for each field needing a name prefix.
type namePrefixTransformer struct { type namePrefixTransformer struct {
prefix string prefix string
pathConfigs []config.PathConfig fieldSpecsToUse []config.FieldSpec
skipPathConfigs []config.PathConfig fieldSpecsToSkip []config.FieldSpec
} }
var _ Transformer = &namePrefixTransformer{} var _ Transformer = &namePrefixTransformer{}
var skipNamePrefixPathConfigs = []config.PathConfig{ var prefixFieldSpecsToSkip = []config.FieldSpec{
{ {
Gvk: gvk.Gvk{Kind: "CustomResourceDefinition"}, Gvk: gvk.Gvk{Kind: "CustomResourceDefinition"},
}, },
} }
// deprecateNamePrefixPathConfig will be moved into skipNamePrefixPathConfigs in next release // deprecateNamePrefixFieldSpec will be moved into prefixFieldSpecsToSkip in next release
var deprecateNamePrefixPathConfig = config.PathConfig{ var deprecateNamePrefixFieldSpec = config.FieldSpec{
Gvk: gvk.Gvk{Kind: "Namespace"}, Gvk: gvk.Gvk{Kind: "Namespace"},
} }
// NewNamePrefixTransformer construct a namePrefixTransformer. // NewNamePrefixTransformer construct a namePrefixTransformer.
func NewNamePrefixTransformer(np string, pc []config.PathConfig) (Transformer, error) { func NewNamePrefixTransformer(np string, pc []config.FieldSpec) (Transformer, error) {
if len(np) == 0 { if len(np) == 0 {
return NewNoOpTransformer(), nil return NewNoOpTransformer(), nil
} }
if pc == nil { if pc == nil {
return nil, errors.New("pathConfigs is not expected to be nil") return nil, errors.New("fieldSpecs is not expected to be nil")
} }
return &namePrefixTransformer{pathConfigs: pc, prefix: np, skipPathConfigs: skipNamePrefixPathConfigs}, nil return &namePrefixTransformer{fieldSpecsToUse: pc, prefix: np, fieldSpecsToSkip: prefixFieldSpecsToSkip}, nil
} }
// Transform prepends the name prefix. // Transform prepends the name prefix.
@@ -64,7 +64,7 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
for id := range m { for id := range m {
found := false found := false
for _, path := range o.skipPathConfigs { for _, path := range o.fieldSpecsToSkip {
if id.Gvk().IsSelected(&path.Gvk) { if id.Gvk().IsSelected(&path.Gvk) {
found = true found = true
break break
@@ -77,11 +77,11 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
} }
for id := range mf { for id := range mf {
if id.Gvk().IsSelected(&deprecateNamePrefixPathConfig.Gvk) { if id.Gvk().IsSelected(&deprecateNamePrefixFieldSpec.Gvk) {
log.Println("Adding nameprefix to Namespace resource will be deprecated in next release.") log.Println("Adding nameprefix to Namespace resource will be deprecated in next release.")
} }
objMap := mf[id].Map() objMap := mf[id].Map()
for _, path := range o.pathConfigs { for _, path := range o.fieldSpecsToUse {
if !id.Gvk().IsSelected(&path.Gvk) { if !id.Gvk().IsSelected(&path.Gvk) {
continue continue
} }

View File

@@ -9,15 +9,15 @@ import (
) )
type refvarTransformer struct { type refvarTransformer struct {
pathConfigs []config.PathConfig fieldSpecs []config.FieldSpec
vars map[string]string vars map[string]string
} }
// NewRefVarTransformer returns a Trasformer that replaces $(VAR) style variables with values. // NewRefVarTransformer returns a Trasformer that replaces $(VAR) style variables with values.
func NewRefVarTransformer(vars map[string]string, p []config.PathConfig) Transformer { func NewRefVarTransformer(vars map[string]string, p []config.FieldSpec) Transformer {
return &refvarTransformer{ return &refvarTransformer{
vars: vars, vars: vars,
pathConfigs: p, fieldSpecs: p,
} }
} }
@@ -33,7 +33,7 @@ func NewRefVarTransformer(vars map[string]string, p []config.PathConfig) Transfo
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error { func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
for resId := range resources { for resId := range resources {
objMap := resources[resId].Map() objMap := resources[resId].Map()
for _, pc := range rv.pathConfigs { for _, pc := range rv.fieldSpecs {
if !resId.Gvk().IsSelected(&pc.Gvk) { if !resId.Gvk().IsSelected(&pc.Gvk) {
continue continue
} }