mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-10 16:42:51 +00:00
Merge pull request #462 from monopole/fixTransformConfigNames
Fix names/doc in transformation config code.
This commit is contained in:
@@ -24,8 +24,6 @@ import (
|
||||
"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{}
|
||||
|
||||
var _ transformers.Transformer = &nameHashTransformer{}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (o *saveOptions) Complete(fsys fs.FileSystem) error {
|
||||
|
||||
// RunSave saves the default transformer configurations local directory
|
||||
func (o *saveOptions) RunSave(fsys fs.FileSystem) error {
|
||||
m := defaultconfig.GetDefaultPathConfigStrings()
|
||||
m := defaultconfig.GetDefaultFieldSpecsAsMap()
|
||||
for tname, tcfg := range m {
|
||||
filename := filepath.Join(o.saveDirectory, tname+".yaml")
|
||||
err := fsys.WriteFile(filename, []byte(tcfg))
|
||||
|
||||
@@ -132,8 +132,8 @@ func (kt *KustTarget) loadCustomizedResMap() (resmap.ResMap, error) {
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "loadResMapFromBasesAndResources"))
|
||||
}
|
||||
crdPathConfigs, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds)
|
||||
kt.tcfg = kt.tcfg.Merge(crdPathConfigs)
|
||||
crdTc, err := config.NewFactory(kt.ldr).LoadCRDs(kt.kustomization.Crds)
|
||||
kt.tcfg = kt.tcfg.Merge(crdTc)
|
||||
if err != nil {
|
||||
errs.Append(errors.Wrap(err, "LoadCRDs"))
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const commonAnnotationPathConfigs = `
|
||||
const commonAnnotationFieldSpecs = `
|
||||
commonAnnotations:
|
||||
- path: metadata/annotations
|
||||
create: true
|
||||
|
||||
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
package defaultconfig
|
||||
|
||||
const commonLabelPathConfigs = `
|
||||
const commonLabelFieldSpecs = `
|
||||
commonLabels:
|
||||
- path: metadata/labels
|
||||
create: true
|
||||
|
||||
@@ -22,27 +22,28 @@ import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// GetDefaultPathConfigs returns the default pathConfigs data
|
||||
func GetDefaultPathConfigs() []byte {
|
||||
// GetDefaultFieldSpecs returns default fieldSpecs.
|
||||
func GetDefaultFieldSpecs() []byte {
|
||||
configData := [][]byte{
|
||||
[]byte(namePrefixPathConfigs),
|
||||
[]byte(commonLabelPathConfigs),
|
||||
[]byte(commonAnnotationPathConfigs),
|
||||
[]byte(namespacePathConfigs),
|
||||
[]byte(varReferencePathConfigs),
|
||||
[]byte(nameReferencePathConfigs),
|
||||
[]byte(namePrefixFieldSpecs),
|
||||
[]byte(commonLabelFieldSpecs),
|
||||
[]byte(commonAnnotationFieldSpecs),
|
||||
[]byte(namespaceFieldSpecs),
|
||||
[]byte(varReferenceFieldSpecs),
|
||||
[]byte(nameReferenceFieldSpecs),
|
||||
}
|
||||
return bytes.Join(configData, []byte("\n"))
|
||||
}
|
||||
|
||||
// GetDefaultPathConfigStrings returns the default pathConfigs in string format
|
||||
func GetDefaultPathConfigStrings() map[string]string {
|
||||
// GetDefaultFieldSpecsAsMap returns default fieldSpecs
|
||||
// as a string->string map.
|
||||
func GetDefaultFieldSpecsAsMap() map[string]string {
|
||||
result := make(map[string]string)
|
||||
result["nameprefix"] = namePrefixPathConfigs
|
||||
result["commonlabels"] = commonLabelPathConfigs
|
||||
result["commonannotations"] = commonAnnotationPathConfigs
|
||||
result["namespace"] = namespacePathConfigs
|
||||
result["varreference"] = varReferencePathConfigs
|
||||
result["namereference"] = namespacePathConfigs
|
||||
result["nameprefix"] = namePrefixFieldSpecs
|
||||
result["commonlabels"] = commonLabelFieldSpecs
|
||||
result["commonannotations"] = commonAnnotationFieldSpecs
|
||||
result["namespace"] = namespaceFieldSpecs
|
||||
result["varreference"] = varReferenceFieldSpecs
|
||||
result["namereference"] = nameReferenceFieldSpecs
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
namePrefixPathConfigs = `
|
||||
namePrefixFieldSpecs = `
|
||||
namePrefix:
|
||||
- path: metadata/name
|
||||
`
|
||||
|
||||
@@ -17,26 +17,26 @@ limitations under the License.
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
nameReferencePathConfigs = `
|
||||
nameReferenceFieldSpecs = `
|
||||
nameReference:
|
||||
- kind: Deployment
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ReplicationController
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ReplicaSet
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/scaleTargetRef/name
|
||||
kind: HorizontalPodAutoscaler
|
||||
|
||||
- kind: ConfigMap
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/configMap/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
@@ -119,7 +119,7 @@ nameReference:
|
||||
|
||||
- kind: Secret
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/secret/secretName
|
||||
version: v1
|
||||
kind: Pod
|
||||
@@ -229,7 +229,7 @@ nameReference:
|
||||
|
||||
- kind: Service
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/serviceName
|
||||
kind: StatefulSet
|
||||
group: apps
|
||||
@@ -240,14 +240,14 @@ nameReference:
|
||||
|
||||
- kind: Role
|
||||
group: rbac.authorization.k8s.io
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: roleRef/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
|
||||
- kind: ClusterRole
|
||||
group: rbac.authorization.k8s.io
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: roleRef/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
@@ -257,7 +257,7 @@ nameReference:
|
||||
|
||||
- kind: ServiceAccount
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: subjects/name
|
||||
kind: RoleBinding
|
||||
group: rbac.authorization.k8s.io
|
||||
@@ -281,7 +281,7 @@ nameReference:
|
||||
|
||||
- kind: PersistentVolumeClaim
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/persistentVolumeClaim/claimName
|
||||
kind: Pod
|
||||
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
|
||||
@@ -299,7 +299,7 @@ nameReference:
|
||||
|
||||
- kind: PersistentVolume
|
||||
version: v1
|
||||
pathConfigs:
|
||||
fieldSpecs:
|
||||
- path: spec/volumeName
|
||||
kind: PersistentVolumeClaim
|
||||
`
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
namespacePathConfigs = `
|
||||
namespaceFieldSpecs = `
|
||||
namespace:
|
||||
- path: metadata/namespace
|
||||
create: true
|
||||
|
||||
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package defaultconfig
|
||||
|
||||
const (
|
||||
varReferencePathConfigs = `
|
||||
varReferenceFieldSpecs = `
|
||||
varReference:
|
||||
- path: spec/template/spec/initContainers/command
|
||||
kind: StatefulSet
|
||||
|
||||
@@ -78,7 +78,7 @@ func (tf *Factory) EmptyConfig() *TransformerConfig {
|
||||
// This should never fail, hence the Fatal panic.
|
||||
func (tf *Factory) DefaultConfig() *TransformerConfig {
|
||||
c, err := makeTransformerConfigFromBytes(
|
||||
defaultconfig.GetDefaultPathConfigs())
|
||||
defaultconfig.GetDefaultFieldSpecs())
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to make default transformconfig: %v", err)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namePrefix:
|
||||
fakeFS.WriteFile("transformerconfig/test/config.yaml", []byte(transformerConfig))
|
||||
ldr := loader.NewFileLoader(fakeFS)
|
||||
expected := &TransformerConfig{
|
||||
NamePrefix: []PathConfig{
|
||||
NamePrefix: []FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{Kind: "SomeKind"},
|
||||
Path: "nameprefix/path",
|
||||
|
||||
@@ -27,15 +27,15 @@ import (
|
||||
|
||||
// LoadCRDs parse CRD schemas from paths into a TransformerConfig
|
||||
func (tf *Factory) LoadCRDs(paths []string) (*TransformerConfig, error) {
|
||||
pathConfigs := tf.EmptyConfig()
|
||||
tc := tf.EmptyConfig()
|
||||
for _, path := range paths {
|
||||
pathConfig, err := tf.loadCRD(path)
|
||||
otherTc, err := tf.loadCRD(path)
|
||||
if err != nil {
|
||||
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) {
|
||||
@@ -57,13 +57,13 @@ func (tf *Factory) loadCRD(path string) (*TransformerConfig, error) {
|
||||
|
||||
crds := getCRDs(types)
|
||||
for crd, k := range crds {
|
||||
crdPathConfigs := tf.EmptyConfig()
|
||||
err = getCRDPathConfig(
|
||||
types, crd, crd, k, []string{}, crdPathConfigs)
|
||||
tc := tf.EmptyConfig()
|
||||
err = loadCrdIntoConfig(
|
||||
types, crd, crd, k, []string{}, tc)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result = result.Merge(crdPathConfigs)
|
||||
result = result.Merge(tc)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@@ -88,10 +88,11 @@ func getCRDs(types map[string]common.OpenAPIDefinition) map[string]gvk.Gvk {
|
||||
return crds
|
||||
}
|
||||
|
||||
// getCRDPathConfig gets pathConfigs for one CRD recursively
|
||||
func getCRDPathConfig(
|
||||
types map[string]common.OpenAPIDefinition, atype string, crd string, in gvk.Gvk,
|
||||
path []string, configs *TransformerConfig) error {
|
||||
// loadCrdIntoConfig loads a CRD spec into a TransformerConfig
|
||||
func loadCrdIntoConfig(
|
||||
types map[string]common.OpenAPIDefinition,
|
||||
atype string, crd string, in gvk.Gvk,
|
||||
path []string, config *TransformerConfig) error {
|
||||
if _, ok := types[crd]; !ok {
|
||||
return nil
|
||||
}
|
||||
@@ -99,8 +100,8 @@ func getCRDPathConfig(
|
||||
for propname, property := range types[atype].Schema.SchemaProps.Properties {
|
||||
_, annotate := property.Extensions.GetString(Annotation)
|
||||
if annotate {
|
||||
configs.AddAnnotationPathConfig(
|
||||
PathConfig{
|
||||
config.AddAnnotationFieldSpec(
|
||||
FieldSpec{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: in,
|
||||
Path: strings.Join(append(path, propname), "/"),
|
||||
@@ -109,8 +110,8 @@ func getCRDPathConfig(
|
||||
}
|
||||
_, label := property.Extensions.GetString(LabelSelector)
|
||||
if label {
|
||||
configs.AddLabelPathConfig(
|
||||
PathConfig{
|
||||
config.AddLabelFieldSpec(
|
||||
FieldSpec{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: in,
|
||||
Path: strings.Join(append(path, propname), "/"),
|
||||
@@ -119,8 +120,8 @@ func getCRDPathConfig(
|
||||
}
|
||||
_, identity := property.Extensions.GetString(Identity)
|
||||
if identity {
|
||||
configs.AddPrefixPathConfig(
|
||||
PathConfig{
|
||||
config.AddPrefixFieldSpec(
|
||||
FieldSpec{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: in,
|
||||
Path: strings.Join(append(path, propname), "/"),
|
||||
@@ -135,9 +136,9 @@ func getCRDPathConfig(
|
||||
if !ok {
|
||||
nameKey = "name"
|
||||
}
|
||||
configs.AddNamereferencePathConfig(ReferencePathConfig{
|
||||
config.AddNamereferenceFieldSpec(NameBackReferences{
|
||||
Gvk: gvk.Gvk{Kind: kind, Version: version},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: in,
|
||||
@@ -149,7 +150,9 @@ func getCRDPathConfig(
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -25,6 +25,12 @@ import (
|
||||
"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 (
|
||||
crdContent = `
|
||||
{
|
||||
@@ -149,10 +155,10 @@ func makeLoader(t *testing.T) ifc.Loader {
|
||||
}
|
||||
|
||||
func TestLoadCRDs(t *testing.T) {
|
||||
refpathconfigs := []ReferencePathConfig{
|
||||
nbrs := []NameBackReferences{
|
||||
{
|
||||
Gvk: gvk.Gvk{Kind: "Secret", Version: "v1"},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: gvk.Gvk{Kind: "MyKind"},
|
||||
@@ -162,7 +168,7 @@ func TestLoadCRDs(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Gvk: gvk.Gvk{Kind: "Bee", Version: "v1beta1"},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
CreateIfNotPresent: false,
|
||||
Gvk: gvk.Gvk{Kind: "MyKind"},
|
||||
@@ -172,14 +178,14 @@ func TestLoadCRDs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
expected := &TransformerConfig{
|
||||
NameReference: refpathconfigs,
|
||||
expectedTc := &TransformerConfig{
|
||||
NameReference: nbrs,
|
||||
}
|
||||
|
||||
pathconfig, _ := NewFactory(makeLoader(t)).LoadCRDs(
|
||||
actualTc, _ := NewFactory(makeLoader(t)).LoadCRDs(
|
||||
[]string{"/testpath/crd.json"})
|
||||
|
||||
if !reflect.DeepEqual(pathconfig, expected) {
|
||||
t.Fatalf("expected\n %v\n but got\n %v\n", expected, pathconfig)
|
||||
if !reflect.DeepEqual(actualTc, expectedTc) {
|
||||
t.Fatalf("expected\n %v\n but got\n %v\n", expectedTc, actualTc)
|
||||
}
|
||||
}
|
||||
|
||||
87
pkg/transformers/config/fieldspec.go
Normal file
87
pkg/transformers/config/fieldspec.go
Normal 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
|
||||
}
|
||||
@@ -37,8 +37,8 @@ func TestPathSlice(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, p := range paths {
|
||||
pathConfig := PathConfig{Path: p.input}
|
||||
actual := pathConfig.PathSlice()
|
||||
fs := FieldSpec{Path: p.input}
|
||||
actual := fs.PathSlice()
|
||||
if !reflect.DeepEqual(actual, p.parsed) {
|
||||
t.Fatalf("expected %v, but got %v", p.parsed, actual)
|
||||
}
|
||||
91
pkg/transformers/config/namebackreferences.go
Normal file
91
pkg/transformers/config/namebackreferences.go
Normal 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
|
||||
}
|
||||
106
pkg/transformers/config/namebackreferences_test.go
Normal file
106
pkg/transformers/config/namebackreferences_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -22,30 +22,30 @@ import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
type rpcSlice []ReferencePathConfig
|
||||
type nbrSlice []NameBackReferences
|
||||
|
||||
func (s rpcSlice) Len() int { return len(s) }
|
||||
func (s rpcSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s rpcSlice) Less(i, j int) bool {
|
||||
func (s nbrSlice) Len() int { return len(s) }
|
||||
func (s nbrSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s nbrSlice) Less(i, j int) bool {
|
||||
return s[i].Gvk.IsLessThan(s[j].Gvk)
|
||||
}
|
||||
|
||||
type pcSlice []PathConfig
|
||||
type fsSlice []FieldSpec
|
||||
|
||||
func (s pcSlice) Len() int { return len(s) }
|
||||
func (s pcSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s pcSlice) Less(i, j int) bool {
|
||||
func (s fsSlice) Len() int { return len(s) }
|
||||
func (s fsSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s fsSlice) Less(i, j int) bool {
|
||||
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 {
|
||||
NamePrefix pcSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
|
||||
NameSpace pcSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
CommonLabels pcSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
|
||||
CommonAnnotations pcSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
|
||||
NameReference rpcSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
|
||||
VarReference pcSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
||||
NamePrefix fsSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
|
||||
NameSpace fsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
CommonLabels fsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
|
||||
CommonAnnotations fsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
|
||||
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
|
||||
VarReference fsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
|
||||
}
|
||||
|
||||
// sortFields provides determinism in logging, tests, etc.
|
||||
@@ -58,24 +58,24 @@ func (t *TransformerConfig) sortFields() {
|
||||
sort.Sort(t.VarReference)
|
||||
}
|
||||
|
||||
// AddPrefixPathConfig adds a PathConfig to NamePrefix
|
||||
func (t *TransformerConfig) AddPrefixPathConfig(config PathConfig) {
|
||||
t.NamePrefix = append(t.NamePrefix, config)
|
||||
// AddPrefixFieldSpec adds a FieldSpec to NamePrefix
|
||||
func (t *TransformerConfig) AddPrefixFieldSpec(fs FieldSpec) {
|
||||
t.NamePrefix = append(t.NamePrefix, fs)
|
||||
}
|
||||
|
||||
// AddLabelPathConfig adds a PathConfig to CommonLabels
|
||||
func (t *TransformerConfig) AddLabelPathConfig(config PathConfig) {
|
||||
t.CommonLabels = append(t.CommonLabels, config)
|
||||
// AddLabelFieldSpec adds a FieldSpec to CommonLabels
|
||||
func (t *TransformerConfig) AddLabelFieldSpec(fs FieldSpec) {
|
||||
t.CommonLabels = append(t.CommonLabels, fs)
|
||||
}
|
||||
|
||||
// AddAnnotationPathConfig adds a PathConfig to CommonAnnotations
|
||||
func (t *TransformerConfig) AddAnnotationPathConfig(config PathConfig) {
|
||||
t.CommonAnnotations = append(t.CommonAnnotations, config)
|
||||
// AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
|
||||
func (t *TransformerConfig) AddAnnotationFieldSpec(fs FieldSpec) {
|
||||
t.CommonAnnotations = append(t.CommonAnnotations, fs)
|
||||
}
|
||||
|
||||
// AddNamereferencePathConfig adds a ReferencePathConfig to NameReference
|
||||
func (t *TransformerConfig) AddNamereferencePathConfig(config ReferencePathConfig) {
|
||||
t.NameReference = mergeNameReferencePathConfigs(t.NameReference, []ReferencePathConfig{config})
|
||||
// AddNamereferenceFieldSpec adds a NameBackReferences to NameReference
|
||||
func (t *TransformerConfig) AddNamereferenceFieldSpec(nbrs NameBackReferences) {
|
||||
t.NameReference = mergeNameBackReferences(t.NameReference, []NameBackReferences{nbrs})
|
||||
}
|
||||
|
||||
// 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.CommonLabels = append(t.CommonLabels, input.CommonLabels...)
|
||||
merged.VarReference = append(t.VarReference, input.VarReference...)
|
||||
merged.NameReference = mergeNameReferencePathConfigs(t.NameReference, input.NameReference)
|
||||
merged.NameReference = mergeNameBackReferences(t.NameReference, input.NameReference)
|
||||
merged.sortFields()
|
||||
return merged
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/gvk"
|
||||
)
|
||||
|
||||
func TestAddNameReferencePathConfigs(t *testing.T) {
|
||||
func TestAddNamereferenceFieldSpec(t *testing.T) {
|
||||
cfg := &TransformerConfig{}
|
||||
|
||||
pathConfig := ReferencePathConfig{
|
||||
nbrs := NameBackReferences{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindA",
|
||||
},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindB",
|
||||
@@ -42,42 +42,42 @@ func TestAddNameReferencePathConfigs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
cfg.AddNamereferencePathConfig(pathConfig)
|
||||
cfg.AddNamereferenceFieldSpec(nbrs)
|
||||
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{}
|
||||
|
||||
pathConfig := PathConfig{
|
||||
fieldSpec := FieldSpec{
|
||||
Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"},
|
||||
Path: "path/to/a/field",
|
||||
CreateIfNotPresent: true,
|
||||
}
|
||||
|
||||
cfg.AddPrefixPathConfig(pathConfig)
|
||||
cfg.AddPrefixFieldSpec(fieldSpec)
|
||||
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 {
|
||||
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 {
|
||||
t.Fatalf("failed to add nameprefix pathconfig")
|
||||
t.Fatalf("failed to add nameprefix FieldSpec")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
nameReference := []ReferencePathConfig{
|
||||
nameReference := []NameBackReferences{
|
||||
{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindA",
|
||||
},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindB",
|
||||
@@ -91,7 +91,7 @@ func TestMerge(t *testing.T) {
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindA",
|
||||
},
|
||||
PathConfigs: []PathConfig{
|
||||
FieldSpecs: []FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "KindC",
|
||||
@@ -102,7 +102,7 @@ func TestMerge(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
pathConfigs := []PathConfig{
|
||||
fieldSpecs := []FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{Group: "GroupA", Kind: "KindB"},
|
||||
Path: "path/to/a/field",
|
||||
@@ -115,28 +115,28 @@ func TestMerge(t *testing.T) {
|
||||
},
|
||||
}
|
||||
cfga := &TransformerConfig{}
|
||||
cfga.AddNamereferencePathConfig(nameReference[0])
|
||||
cfga.AddPrefixPathConfig(pathConfigs[0])
|
||||
cfga.AddNamereferenceFieldSpec(nameReference[0])
|
||||
cfga.AddPrefixFieldSpec(fieldSpecs[0])
|
||||
|
||||
cfgb := &TransformerConfig{}
|
||||
cfgb.AddNamereferencePathConfig(nameReference[1])
|
||||
cfgb.AddPrefixPathConfig(pathConfigs[1])
|
||||
cfgb.AddNamereferenceFieldSpec(nameReference[1])
|
||||
cfgb.AddPrefixFieldSpec(fieldSpecs[1])
|
||||
|
||||
actual := cfga.Merge(cfgb)
|
||||
|
||||
if len(actual.NamePrefix) != 2 {
|
||||
t.Fatal("merge failed for namePrefix pathconfig")
|
||||
t.Fatal("merge failed for namePrefix FieldSpec")
|
||||
}
|
||||
|
||||
if len(actual.NameReference) != 1 {
|
||||
t.Fatal("merge failed for namereference pathconfig")
|
||||
t.Fatal("merge failed for namereference FieldSpec")
|
||||
}
|
||||
|
||||
expected := &TransformerConfig{}
|
||||
expected.AddNamereferencePathConfig(nameReference[0])
|
||||
expected.AddNamereferencePathConfig(nameReference[1])
|
||||
expected.AddPrefixPathConfig(pathConfigs[0])
|
||||
expected.AddPrefixPathConfig(pathConfigs[1])
|
||||
expected.AddNamereferenceFieldSpec(nameReference[0])
|
||||
expected.AddNamereferenceFieldSpec(nameReference[1])
|
||||
expected.AddPrefixFieldSpec(fieldSpecs[0])
|
||||
expected.AddPrefixFieldSpec(fieldSpecs[1])
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("expected: %v\n but got: %v\n", expected, actual)
|
||||
|
||||
@@ -24,34 +24,36 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
// mapTransformer contains a map string->string and path configs
|
||||
// The map will be applied to the fields specified in path configs.
|
||||
// mapTransformer applies a string->string map to fieldSpecs.
|
||||
type mapTransformer struct {
|
||||
m map[string]string
|
||||
pathConfigs []config.PathConfig
|
||||
m map[string]string
|
||||
fieldSpecs []config.FieldSpec
|
||||
}
|
||||
|
||||
var _ Transformer = &mapTransformer{}
|
||||
|
||||
// NewLabelsMapTransformer construct a mapTransformer with a given pathConfig slice
|
||||
func NewLabelsMapTransformer(m map[string]string, p []config.PathConfig) (Transformer, error) {
|
||||
return NewMapTransformer(p, m)
|
||||
// NewLabelsMapTransformer constructs a mapTransformer.
|
||||
func NewLabelsMapTransformer(
|
||||
m map[string]string, fs []config.FieldSpec) (Transformer, error) {
|
||||
return NewMapTransformer(fs, m)
|
||||
}
|
||||
|
||||
// NewAnnotationsMapTransformer construct a mapTransformer with a given pathConfig slice
|
||||
func NewAnnotationsMapTransformer(m map[string]string, p []config.PathConfig) (Transformer, error) {
|
||||
return NewMapTransformer(p, m)
|
||||
// NewAnnotationsMapTransformer construct a mapTransformer.
|
||||
func NewAnnotationsMapTransformer(
|
||||
m map[string]string, fs []config.FieldSpec) (Transformer, error) {
|
||||
return NewMapTransformer(fs, m)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return NewNoOpTransformer(), 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
|
||||
@@ -59,7 +61,7 @@ func NewMapTransformer(pc []config.PathConfig, m map[string]string) (Transformer
|
||||
func (o *mapTransformer) Transform(m resmap.ResMap) error {
|
||||
for id := range m {
|
||||
objMap := m[id].Map()
|
||||
for _, path := range o.pathConfigs {
|
||||
for _, path := range o.fieldSpecs {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -26,36 +26,36 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
// nameReferenceTransformer contains the referencing info between 2 GroupVersionKinds
|
||||
type nameReferenceTransformer struct {
|
||||
pathConfigs []config.ReferencePathConfig
|
||||
backRefs []config.NameBackReferences
|
||||
}
|
||||
|
||||
var _ Transformer = &nameReferenceTransformer{}
|
||||
|
||||
// NewNameReferenceTransformer constructs a nameReferenceTransformer
|
||||
// with a given Reference PathConfig slice
|
||||
func NewNameReferenceTransformer(pc []config.ReferencePathConfig) (Transformer, error) {
|
||||
if pc == nil {
|
||||
return nil, errors.New("pathConfigs is not expected to be nil")
|
||||
// with a given slice of NameBackReferences.
|
||||
func NewNameReferenceTransformer(
|
||||
br []config.NameBackReferences) (Transformer, error) {
|
||||
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
|
||||
// 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()
|
||||
func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error {
|
||||
for id := range m {
|
||||
objMap := m[id].Map()
|
||||
for _, referencePathConfig := range o.pathConfigs {
|
||||
for _, path := range referencePathConfig.PathConfigs {
|
||||
for _, backRef := range o.backRefs {
|
||||
for _, path := range backRef.FieldSpecs {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
err := mutateField(objMap, path.PathSlice(), path.CreateIfNotPresent,
|
||||
o.updateNameReference(referencePathConfig.Gvk, m.FilterBy(id)))
|
||||
o.updateNameReference(backRef.Gvk, m.FilterBy(id)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ import (
|
||||
)
|
||||
|
||||
type namespaceTransformer struct {
|
||||
namespace string
|
||||
pathConfigs []config.PathConfig
|
||||
skipPathConfigs []config.PathConfig
|
||||
namespace string
|
||||
fieldSpecsToUse []config.FieldSpec
|
||||
fieldSpecsToSkip []config.FieldSpec
|
||||
}
|
||||
|
||||
var skipNamespacePathConfigs = []config.PathConfig{
|
||||
var namespaceFieldSpecsToSkip = []config.FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "Namespace",
|
||||
@@ -54,15 +54,15 @@ var skipNamespacePathConfigs = []config.PathConfig{
|
||||
var _ Transformer = &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 {
|
||||
return NewNoOpTransformer()
|
||||
}
|
||||
|
||||
return &namespaceTransformer{
|
||||
namespace: ns,
|
||||
pathConfigs: cf,
|
||||
skipPathConfigs: skipNamespacePathConfigs,
|
||||
namespace: ns,
|
||||
fieldSpecsToUse: cf,
|
||||
fieldSpecsToSkip: namespaceFieldSpecsToSkip,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
|
||||
|
||||
for id := range m {
|
||||
found := false
|
||||
for _, path := range o.skipPathConfigs {
|
||||
for _, path := range o.fieldSpecsToSkip {
|
||||
if id.Gvk().IsSelected(&path.Gvk) {
|
||||
found = true
|
||||
break
|
||||
@@ -86,7 +86,7 @@ func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
|
||||
|
||||
for id := range mf {
|
||||
objMap := mf[id].Map()
|
||||
for _, path := range o.pathConfigs {
|
||||
for _, path := range o.fieldSpecsToUse {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -26,36 +26,36 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
)
|
||||
|
||||
// namePrefixTransformer contains the prefix and the path config for each field that
|
||||
// the name prefix will be applied.
|
||||
// namePrefixTransformer contains the prefix and the FieldSpecs
|
||||
// for each field needing a name prefix.
|
||||
type namePrefixTransformer struct {
|
||||
prefix string
|
||||
pathConfigs []config.PathConfig
|
||||
skipPathConfigs []config.PathConfig
|
||||
prefix string
|
||||
fieldSpecsToUse []config.FieldSpec
|
||||
fieldSpecsToSkip []config.FieldSpec
|
||||
}
|
||||
|
||||
var _ Transformer = &namePrefixTransformer{}
|
||||
|
||||
var skipNamePrefixPathConfigs = []config.PathConfig{
|
||||
var prefixFieldSpecsToSkip = []config.FieldSpec{
|
||||
{
|
||||
Gvk: gvk.Gvk{Kind: "CustomResourceDefinition"},
|
||||
},
|
||||
}
|
||||
|
||||
// deprecateNamePrefixPathConfig will be moved into skipNamePrefixPathConfigs in next release
|
||||
var deprecateNamePrefixPathConfig = config.PathConfig{
|
||||
// deprecateNamePrefixFieldSpec will be moved into prefixFieldSpecsToSkip in next release
|
||||
var deprecateNamePrefixFieldSpec = config.FieldSpec{
|
||||
Gvk: gvk.Gvk{Kind: "Namespace"},
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return NewNoOpTransformer(), 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.
|
||||
@@ -64,7 +64,7 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
||||
|
||||
for id := range m {
|
||||
found := false
|
||||
for _, path := range o.skipPathConfigs {
|
||||
for _, path := range o.fieldSpecsToSkip {
|
||||
if id.Gvk().IsSelected(&path.Gvk) {
|
||||
found = true
|
||||
break
|
||||
@@ -77,11 +77,11 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
||||
}
|
||||
|
||||
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.")
|
||||
}
|
||||
objMap := mf[id].Map()
|
||||
for _, path := range o.pathConfigs {
|
||||
for _, path := range o.fieldSpecsToUse {
|
||||
if !id.Gvk().IsSelected(&path.Gvk) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -9,15 +9,15 @@ import (
|
||||
)
|
||||
|
||||
type refvarTransformer struct {
|
||||
pathConfigs []config.PathConfig
|
||||
vars map[string]string
|
||||
fieldSpecs []config.FieldSpec
|
||||
vars map[string]string
|
||||
}
|
||||
|
||||
// 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{
|
||||
vars: vars,
|
||||
pathConfigs: p,
|
||||
vars: vars,
|
||||
fieldSpecs: p,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func NewRefVarTransformer(vars map[string]string, p []config.PathConfig) Transfo
|
||||
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
|
||||
for resId := range resources {
|
||||
objMap := resources[resId].Map()
|
||||
for _, pc := range rv.pathConfigs {
|
||||
for _, pc := range rv.fieldSpecs {
|
||||
if !resId.Gvk().IsSelected(&pc.Gvk) {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user