Drain pkg/transformers.

This commit is contained in:
jregan
2019-10-20 07:25:54 -07:00
parent 5de000ee3d
commit c90e0a4080
57 changed files with 335 additions and 624 deletions

View File

@@ -1,30 +1,18 @@
/*
Copyright 2018 The Kubernetes Authors.
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
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
package accumulator
import (
"encoding/json"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"strings"
"github.com/go-openapi/spec"
"github.com/pkg/errors"
"k8s.io/kube-openapi/pkg/common"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
"sigs.k8s.io/yaml"
)
@@ -34,8 +22,8 @@ type nameToApiMap map[string]common.OpenAPIDefinition
// LoadConfigFromCRDs parse CRD schemas from paths into a TransformerConfig
func LoadConfigFromCRDs(
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
tc := MakeEmptyConfig()
ldr ifc.Loader, paths []string) (*builtinconfig.TransformerConfig, error) {
tc := builtinconfig.MakeEmptyConfig()
for _, path := range paths {
content, err := ldr.Load(path)
if err != nil {
@@ -66,13 +54,13 @@ func makeNameToApiMap(content []byte) (result nameToApiMap, err error) {
return
}
func makeConfigFromApiMap(m nameToApiMap) (*TransformerConfig, error) {
result := MakeEmptyConfig()
func makeConfigFromApiMap(m nameToApiMap) (*builtinconfig.TransformerConfig, error) {
result := builtinconfig.MakeEmptyConfig()
for name, api := range m {
if !looksLikeAk8sType(api.Schema.SchemaProps.Properties) {
continue
}
tc := MakeEmptyConfig()
tc := builtinconfig.MakeEmptyConfig()
err := loadCrdIntoConfig(
tc, makeGvkFromTypeName(name), m, name, []string{})
if err != nil {
@@ -134,7 +122,7 @@ const (
// loadCrdIntoConfig loads a CRD spec into a TransformerConfig
func loadCrdIntoConfig(
theConfig *TransformerConfig, theGvk resid.Gvk, theMap nameToApiMap,
theConfig *builtinconfig.TransformerConfig, theGvk resid.Gvk, theMap nameToApiMap,
typeName string, path []string) (err error) {
api, ok := theMap[typeName]
if !ok {
@@ -174,7 +162,7 @@ func loadCrdIntoConfig(
nameKey = "name"
}
err = theConfig.AddNamereferenceFieldSpec(
NameBackReferences{
builtinconfig.NameBackReferences{
Gvk: resid.Gvk{Kind: kind, Version: version},
FieldSpecs: []types.FieldSpec{
makeFs(theGvk, append(path, propName, nameKey))},

View File

@@ -1,28 +1,17 @@
/*
Copyright 2018 The Kubernetes Authors.
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
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
package accumulator_test
import (
"reflect"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"testing"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/internal/loadertest"
. "sigs.k8s.io/kustomize/v3/pkg/accumulator"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
)
@@ -156,7 +145,7 @@ func makeLoader(t *testing.T) ifc.Loader {
}
func TestLoadCRDs(t *testing.T) {
nbrs := []NameBackReferences{
nbrs := []builtinconfig.NameBackReferences{
{
Gvk: resid.Gvk{Kind: "Secret", Version: "v1"},
FieldSpecs: []types.FieldSpec{
@@ -179,7 +168,7 @@ func TestLoadCRDs(t *testing.T) {
},
}
expectedTc := &TransformerConfig{
expectedTc := &builtinconfig.TransformerConfig{
NameReference: nbrs,
}

View File

@@ -1,28 +1,28 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package transformers
package accumulator
import (
"fmt"
"log"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/pkg/resource"
"sigs.k8s.io/kustomize/v3/api/transform"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
"sigs.k8s.io/kustomize/v3/pkg/resource"
)
type nameReferenceTransformer struct {
backRefs []config.NameBackReferences
backRefs []builtinconfig.NameBackReferences
}
var _ resmap.Transformer = &nameReferenceTransformer{}
// NewNameReferenceTransformer constructs a nameReferenceTransformer
// newNameReferenceTransformer constructs a nameReferenceTransformer
// with a given slice of NameBackReferences.
func NewNameReferenceTransformer(br []config.NameBackReferences) resmap.Transformer {
func newNameReferenceTransformer(br []builtinconfig.NameBackReferences) resmap.Transformer {
if br == nil {
log.Fatal("backrefs not expected to be nil")
}
@@ -86,7 +86,7 @@ func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error {
if candidates == nil {
candidates = m.SubsetThatCouldBeReferencedByResource(referrer)
}
err := MutateField(
err := transform.MutateField(
referrer.Map(),
fSpec.PathSlice(),
fSpec.CreateIfNotPresent,

View File

@@ -1,12 +1,13 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package transformers
package accumulator
import (
"strings"
"testing"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
@@ -462,7 +463,7 @@ func TestNameReferenceHappyRun(t *testing.T) {
},
}).ResMap()
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
err := nrt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -522,7 +523,7 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
expectedErr: "is expected to contain a name field"},
}
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
for _, test := range tests {
err := nrt.Transform(test.resMap)
if err == nil {
@@ -580,7 +581,7 @@ func TestNameReferencePersistentVolumeHappyRun(t *testing.T) {
m1 := resmaptest_test.NewRmBuilder(t, rf).AddR(v1).AddR(c1).ResMap()
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
if err := nrt.Transform(m1); err != nil {
t.Fatalf("unexpected error: %v", err)
}
@@ -719,7 +720,7 @@ func TestNameReferenceNamespace(t *testing.T) {
ReplaceResource(deploymentMap(ns1, prefixedname, prefixedname, prefixedname)).
ReplaceResource(deploymentMap(ns2, suffixedname, suffixedname, suffixedname)).ResMap()
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
err := nrt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -882,7 +883,7 @@ func TestNameReferenceClusterWide(t *testing.T) {
clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
clusterRole.AppendRefBy(clusterRoleBindingId)
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
err := nrt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -1010,7 +1011,7 @@ func TestNameReferenceNamespaceTransformation(t *testing.T) {
clusterRole, _ := expected.GetByCurrentId(clusterRoleId)
clusterRole.AppendRefBy(clusterRoleBindingId)
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
err := nrt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@@ -1048,7 +1049,7 @@ func TestNameReferenceCandidateSelection(t *testing.T) {
ReplaceResource(deploymentMap("", "p1-deploy1", "p1-cm1-hash", "p1-secret1-hash")).
ResMap()
nrt := NewNameReferenceTransformer(defaultTransformerConfig.NameReference)
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
err := nrt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)

View File

@@ -1,42 +1,30 @@
/*
Copyright 2018 The Kubernetes Authors.
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
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 transformers
package accumulator
import (
"fmt"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/api/transform"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/expansion"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
)
type RefVarTransformer struct {
type refVarTransformer struct {
varMap map[string]interface{}
replacementCounts map[string]int
fieldSpecs []types.FieldSpec
mappingFunc func(string) interface{}
}
// NewRefVarTransformer returns a new RefVarTransformer
// newRefVarTransformer returns a new refVarTransformer
// that replaces $(VAR) style variables with values.
// The fieldSpecs are the places to look for occurrences of $(VAR).
func NewRefVarTransformer(
varMap map[string]interface{}, fs []types.FieldSpec) *RefVarTransformer {
return &RefVarTransformer{
func newRefVarTransformer(
varMap map[string]interface{}, fs []types.FieldSpec) *refVarTransformer {
return &refVarTransformer{
varMap: varMap,
fieldSpecs: fs,
}
@@ -46,7 +34,7 @@ func NewRefVarTransformer(
// embedded instances of $VAR style variables, e.g. a container command string.
// The function returns the string with the variables expanded to their final
// values.
func (rv *RefVarTransformer) replaceVars(in interface{}) (interface{}, error) {
func (rv *refVarTransformer) replaceVars(in interface{}) (interface{}, error) {
switch vt := in.(type) {
case []interface{}:
var xs []interface{}
@@ -90,7 +78,7 @@ func (rv *RefVarTransformer) replaceVars(in interface{}) (interface{}, error) {
// UnusedVars returns slice of Var names that were unused
// after a Transform run.
func (rv *RefVarTransformer) UnusedVars() []string {
func (rv *refVarTransformer) UnusedVars() []string {
var unused []string
for k := range rv.varMap {
_, ok := rv.replacementCounts[k]
@@ -102,14 +90,14 @@ func (rv *RefVarTransformer) UnusedVars() []string {
}
// Transform replaces $(VAR) style variables with values.
func (rv *RefVarTransformer) Transform(m resmap.ResMap) error {
func (rv *refVarTransformer) Transform(m resmap.ResMap) error {
rv.replacementCounts = make(map[string]int)
rv.mappingFunc = expansion.MappingFuncFor(
rv.replacementCounts, rv.varMap)
for _, res := range m.Resources() {
for _, fieldSpec := range rv.fieldSpecs {
if res.OrgId().IsSelected(&fieldSpec.Gvk) {
if err := MutateField(
if err := transform.MutateField(
res.Map(), fieldSpec.PathSlice(),
false, rv.replaceVars); err != nil {
return err

View File

@@ -1,19 +1,21 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package transformers
package accumulator
import (
"reflect"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"testing"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/resmaptest"
"sigs.k8s.io/kustomize/v3/pkg/resource"
)
func TestVarRef(t *testing.T) {
func TestRefVarTransformer(t *testing.T) {
type given struct {
varMap map[string]interface{}
fs []types.FieldSpec
@@ -44,7 +46,8 @@ func TestVarRef(t *testing.T) {
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/nil"},
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/num"},
},
res: resmaptest_test.NewRmBuilder(t, rf).
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -75,7 +78,8 @@ func TestVarRef(t *testing.T) {
}}).ResMap(),
},
expected: expected{
res: resmaptest_test.NewRmBuilder(t, rf).
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
@@ -112,7 +116,7 @@ func TestVarRef(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
// arrange
tr := NewRefVarTransformer(tc.given.varMap, tc.given.fs)
tr := newRefVarTransformer(tc.given.varMap, tc.given.fs)
// act
err := tr.Transform(tc.given.res)

View File

@@ -8,11 +8,10 @@ import (
"log"
"strings"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/transformers"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
)
// ResAccumulator accumulates resources and the rules
@@ -20,14 +19,14 @@ import (
// plus stuff needed to modify the ResMap.
type ResAccumulator struct {
resMap resmap.ResMap
tConfig *config.TransformerConfig
tConfig *builtinconfig.TransformerConfig
varSet types.VarSet
}
func MakeEmptyAccumulator() *ResAccumulator {
ra := &ResAccumulator{}
ra.resMap = resmap.New()
ra.tConfig = &config.TransformerConfig{}
ra.tConfig = &builtinconfig.TransformerConfig{}
ra.varSet = types.NewVarSet()
return ra
}
@@ -53,12 +52,12 @@ func (ra *ResAccumulator) AbsorbAll(
}
func (ra *ResAccumulator) MergeConfig(
tConfig *config.TransformerConfig) (err error) {
tConfig *builtinconfig.TransformerConfig) (err error) {
ra.tConfig, err = ra.tConfig.Merge(tConfig)
return err
}
func (ra *ResAccumulator) GetTransformerConfig() *config.TransformerConfig {
func (ra *ResAccumulator) GetTransformerConfig() *builtinconfig.TransformerConfig {
return ra.tConfig
}
@@ -147,7 +146,7 @@ func (ra *ResAccumulator) ResolveVars() error {
if len(replacementMap) == 0 {
return nil
}
t := transformers.NewRefVarTransformer(
t := newRefVarTransformer(
replacementMap, ra.tConfig.VarReference)
err = ra.Transform(t)
if len(t.UnusedVars()) > 0 {
@@ -162,6 +161,6 @@ func (ra *ResAccumulator) FixBackReferences() (err error) {
if ra.tConfig.NameReference == nil {
return nil
}
return ra.Transform(transformers.NewNameReferenceTransformer(
return ra.Transform(newNameReferenceTransformer(
ra.tConfig.NameReference))
}

View File

@@ -10,6 +10,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct"
@@ -17,12 +18,11 @@ import (
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/resmaptest"
"sigs.k8s.io/kustomize/v3/pkg/resource"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
)
func makeResAccumulator(t *testing.T) (*ResAccumulator, *resource.Factory) {
ra := MakeEmptyAccumulator()
err := ra.MergeConfig(config.MakeDefaultConfig())
err := ra.MergeConfig(builtinconfig.MakeDefaultConfig())
if err != nil {
t.Fatalf("unexpected err: %v", err)
}

View File

@@ -10,17 +10,17 @@ import (
"encoding/json"
"fmt"
"log"
"sigs.k8s.io/kustomize/v3/api/transform"
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/accumulator"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
"sigs.k8s.io/kustomize/v3/pkg/pgmconfig"
"sigs.k8s.io/kustomize/v3/pkg/plugins"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/transformers"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
"sigs.k8s.io/kustomize/v3/plugin/builtin"
"sigs.k8s.io/yaml"
)
@@ -216,7 +216,7 @@ func (kt *KustTarget) AccumulateTarget() (
if err != nil {
return nil, errors.Wrap(err, "accumulating resources")
}
tConfig, err := config.MakeTransformerConfig(
tConfig, err := builtinconfig.MakeTransformerConfig(
kt.ldr, kt.kustomization.Configurations)
if err != nil {
return nil, err
@@ -226,7 +226,7 @@ func (kt *KustTarget) AccumulateTarget() (
return nil, errors.Wrapf(
err, "merging config %v", tConfig)
}
crdTc, err := config.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds)
crdTc, err := accumulator.LoadConfigFromCRDs(kt.ldr, kt.kustomization.Crds)
if err != nil {
return nil, errors.Wrapf(
err, "loading CRDs %v", kt.kustomization.Crds)
@@ -300,7 +300,7 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
return err
}
r = append(r, lts...)
t := transformers.NewMultiTransformer(r)
t := transform.NewMultiTransformer(r)
return ra.Transform(t)
}

View File

@@ -4,10 +4,10 @@
package target
import (
"sigs.k8s.io/kustomize/v3/api/builtinconfig"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/plugins"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
)
// Functions dedicated to configuring the builtin
@@ -42,7 +42,7 @@ func (kt *KustTarget) configureBuiltinGenerators() (
}
func (kt *KustTarget) configureBuiltinTransformers(
tc *config.TransformerConfig) (
tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
for _, bpt := range []plugins.BuiltinPluginType{
plugins.PatchStrategicMergeTransformer,
@@ -120,9 +120,9 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
kt *KustTarget,
bpt plugins.BuiltinPluginType,
f tFactory,
tc *config.TransformerConfig) (result []resmap.Transformer, err error){
tc *builtinconfig.TransformerConfig) (result []resmap.Transformer, err error){
plugins.NamespaceTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
@@ -140,7 +140,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
},
plugins.PatchJson6902Transformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Target types.PatchTarget `json:"target,omitempty" yaml:"target,omitempty"`
@@ -161,7 +161,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.PatchStrategicMergeTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
if len(kt.kustomization.PatchesStrategicMerge) == 0 {
return
@@ -180,7 +180,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.PatchTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
if len(kt.kustomization.Patches) == 0 {
return
@@ -204,7 +204,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.LabelTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Labels map[string]string
@@ -221,7 +221,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.AnnotationsTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Annotations map[string]string
@@ -238,7 +238,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.PrefixSuffixTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Prefix string
@@ -257,7 +257,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.ImageTagTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
ImageTag types.Image
@@ -276,7 +276,7 @@ var transformerConfigurators = map[plugins.BuiltinPluginType]func(
return
},
plugins.ReplicaCountTransformer: func(
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *config.TransformerConfig) (
kt *KustTarget, bpt plugins.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
var c struct {
Replica types.Replica

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 defaultconfig
const commonAnnotationFieldSpecs = `
commonAnnotations:
- path: metadata/annotations
create: true
- path: spec/template/metadata/annotations
create: true
version: v1
kind: ReplicationController
- path: spec/template/metadata/annotations
create: true
kind: Deployment
- path: spec/template/metadata/annotations
create: true
kind: ReplicaSet
- path: spec/template/metadata/annotations
create: true
kind: DaemonSet
- path: spec/template/metadata/annotations
create: true
kind: StatefulSet
- path: spec/template/metadata/annotations
create: true
group: batch
kind: Job
- path: spec/jobTemplate/metadata/annotations
create: true
group: batch
kind: CronJob
- path: spec/jobTemplate/spec/template/metadata/annotations
create: true
group: batch
kind: CronJob
`

View File

@@ -1,162 +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 defaultconfig
const commonLabelFieldSpecs = `
commonLabels:
- path: metadata/labels
create: true
- path: spec/selector
create: true
version: v1
kind: Service
- path: spec/selector
create: true
version: v1
kind: ReplicationController
- path: spec/template/metadata/labels
create: true
version: v1
kind: ReplicationController
- path: spec/selector/matchLabels
create: true
kind: Deployment
- path: spec/template/metadata/labels
create: true
kind: Deployment
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
kind: Deployment
- path: spec/template/spec/affinity/podAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
create: false
group: apps
kind: Deployment
- path: spec/template/spec/affinity/podAntiAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
kind: Deployment
- path: spec/template/spec/affinity/podAntiAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
create: false
group: apps
kind: Deployment
- path: spec/selector/matchLabels
create: true
kind: ReplicaSet
- path: spec/template/metadata/labels
create: true
kind: ReplicaSet
- path: spec/selector/matchLabels
create: true
kind: DaemonSet
- path: spec/template/metadata/labels
create: true
kind: DaemonSet
- path: spec/selector/matchLabels
create: true
group: apps
kind: StatefulSet
- path: spec/template/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
kind: StatefulSet
- path: spec/template/spec/affinity/podAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
create: false
group: apps
kind: StatefulSet
- path: spec/template/spec/affinity/podAntiAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
kind: StatefulSet
- path: spec/template/spec/affinity/podAntiAffinity/requiredDuringSchedulingIgnoredDuringExecution/labelSelector/matchLabels
create: false
group: apps
kind: StatefulSet
- path: spec/volumeClaimTemplates[]/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/selector/matchLabels
create: false
group: batch
kind: Job
- path: spec/template/metadata/labels
create: true
group: batch
kind: Job
- path: spec/jobTemplate/spec/selector/matchLabels
create: false
group: batch
kind: CronJob
- path: spec/jobTemplate/metadata/labels
create: true
group: batch
kind: CronJob
- path: spec/jobTemplate/spec/template/metadata/labels
create: true
group: batch
kind: CronJob
- path: spec/selector/matchLabels
create: false
group: policy
kind: PodDisruptionBudget
- path: spec/podSelector/matchLabels
create: false
group: networking.k8s.io
kind: NetworkPolicy
- path: spec/ingress/from/podSelector/matchLabels
create: false
group: networking.k8s.io
kind: NetworkPolicy
- path: spec/egress/to/podSelector/matchLabels
create: false
group: networking.k8s.io
kind: NetworkPolicy
`

View File

@@ -1,53 +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 defaultconfig provides the default
// transformer configurations
package defaultconfig
import (
"bytes"
)
// GetDefaultFieldSpecs returns default fieldSpecs.
func GetDefaultFieldSpecs() []byte {
configData := [][]byte{
[]byte(namePrefixFieldSpecs),
[]byte(commonLabelFieldSpecs),
[]byte(commonAnnotationFieldSpecs),
[]byte(namespaceFieldSpecs),
[]byte(varReferenceFieldSpecs),
[]byte(nameReferenceFieldSpecs),
[]byte(imagesFieldSpecs),
[]byte(replicasFieldSpecs),
}
return bytes.Join(configData, []byte("\n"))
}
// GetDefaultFieldSpecsAsMap returns default fieldSpecs
// as a string->string map.
func GetDefaultFieldSpecsAsMap() map[string]string {
result := make(map[string]string)
result["nameprefix"] = namePrefixFieldSpecs
result["commonlabels"] = commonLabelFieldSpecs
result["commonannotations"] = commonAnnotationFieldSpecs
result["namespace"] = namespaceFieldSpecs
result["varreference"] = varReferenceFieldSpecs
result["namereference"] = nameReferenceFieldSpecs
result["images"] = imagesFieldSpecs
result["replicas"] = replicasFieldSpecs
return result
}

View File

@@ -1,23 +0,0 @@
/*
Copyright 2019 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 defaultconfig
const (
// imageFieldSpecs is left empty since `containers` and `initContainers`
// of *ANY* kind in *ANY* path are builtin supported in code
imagesFieldSpecs = ``
)

View File

@@ -1,24 +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 defaultconfig
const (
namePrefixFieldSpecs = `
namePrefix:
- path: metadata/name
`
)

View File

@@ -1,360 +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 defaultconfig
const (
nameReferenceFieldSpecs = `
nameReference:
- kind: Deployment
fieldSpecs:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: ReplicationController
fieldSpecs:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: ReplicaSet
fieldSpecs:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: ConfigMap
version: v1
fieldSpecs:
- path: spec/volumes/configMap/name
version: v1
kind: Pod
- path: spec/containers/env/valueFrom/configMapKeyRef/name
version: v1
kind: Pod
- path: spec/initContainers/env/valueFrom/configMapKeyRef/name
version: v1
kind: Pod
- path: spec/containers/envFrom/configMapRef/name
version: v1
kind: Pod
- path: spec/initContainers/envFrom/configMapRef/name
version: v1
kind: Pod
- path: spec/volumes/projected/sources/configMap/name
version: v1
kind: Pod
- path: spec/template/spec/volumes/configMap/name
kind: Deployment
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: Deployment
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: Deployment
- path: spec/template/spec/containers/envFrom/configMapRef/name
kind: Deployment
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
kind: Deployment
- path: spec/template/spec/volumes/projected/sources/configMap/name
kind: Deployment
- path: spec/template/spec/volumes/configMap/name
kind: ReplicaSet
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: ReplicaSet
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: ReplicaSet
- path: spec/template/spec/containers/envFrom/configMapRef/name
kind: ReplicaSet
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
kind: ReplicaSet
- path: spec/template/spec/volumes/projected/sources/configMap/name
kind: ReplicaSet
- path: spec/template/spec/volumes/configMap/name
kind: DaemonSet
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: DaemonSet
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: DaemonSet
- path: spec/template/spec/containers/envFrom/configMapRef/name
kind: DaemonSet
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
kind: DaemonSet
- path: spec/template/spec/volumes/projected/sources/configMap/name
kind: DaemonSet
- path: spec/template/spec/volumes/configMap/name
kind: StatefulSet
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: StatefulSet
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: StatefulSet
- path: spec/template/spec/containers/envFrom/configMapRef/name
kind: StatefulSet
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
kind: StatefulSet
- path: spec/template/spec/volumes/projected/sources/configMap/name
kind: StatefulSet
- path: spec/template/spec/volumes/configMap/name
kind: Job
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: Job
- path: spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: Job
- path: spec/template/spec/containers/envFrom/configMapRef/name
kind: Job
- path: spec/template/spec/initContainers/envFrom/configMapRef/name
kind: Job
- path: spec/template/spec/volumes/projected/sources/configMap/name
kind: Job
- path: spec/jobTemplate/spec/template/spec/volumes/configMap/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/volumes/projected/sources/configMap/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/configMapKeyRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/envFrom/configMapRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/configMapRef/name
kind: CronJob
- kind: Secret
version: v1
fieldSpecs:
- path: spec/volumes/secret/secretName
version: v1
kind: Pod
- path: spec/containers/env/valueFrom/secretKeyRef/name
version: v1
kind: Pod
- path: spec/initContainers/env/valueFrom/secretKeyRef/name
version: v1
kind: Pod
- path: spec/containers/envFrom/secretRef/name
version: v1
kind: Pod
- path: spec/initContainers/envFrom/secretRef/name
version: v1
kind: Pod
- path: spec/imagePullSecrets/name
version: v1
kind: Pod
- path: spec/volumes/projected/sources/secret/name
version: v1
kind: Pod
- path: spec/template/spec/volumes/secret/secretName
kind: Deployment
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: Deployment
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: Deployment
- path: spec/template/spec/containers/envFrom/secretRef/name
kind: Deployment
- path: spec/template/spec/initContainers/envFrom/secretRef/name
kind: Deployment
- path: spec/template/spec/imagePullSecrets/name
kind: Deployment
- path: spec/template/spec/volumes/projected/sources/secret/name
kind: Deployment
- path: spec/template/spec/volumes/secret/secretName
kind: ReplicaSet
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: ReplicaSet
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: ReplicaSet
- path: spec/template/spec/containers/envFrom/secretRef/name
kind: ReplicaSet
- path: spec/template/spec/initContainers/envFrom/secretRef/name
kind: ReplicaSet
- path: spec/template/spec/imagePullSecrets/name
kind: ReplicaSet
- path: spec/template/spec/volumes/projected/sources/secret/name
kind: ReplicaSet
- path: spec/template/spec/volumes/secret/secretName
kind: DaemonSet
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: DaemonSet
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: DaemonSet
- path: spec/template/spec/containers/envFrom/secretRef/name
kind: DaemonSet
- path: spec/template/spec/initContainers/envFrom/secretRef/name
kind: DaemonSet
- path: spec/template/spec/imagePullSecrets/name
kind: DaemonSet
- path: spec/template/spec/volumes/projected/sources/secret/name
kind: DaemonSet
- path: spec/template/spec/volumes/secret/secretName
kind: StatefulSet
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: StatefulSet
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: StatefulSet
- path: spec/template/spec/containers/envFrom/secretRef/name
kind: StatefulSet
- path: spec/template/spec/initContainers/envFrom/secretRef/name
kind: StatefulSet
- path: spec/template/spec/imagePullSecrets/name
kind: StatefulSet
- path: spec/template/spec/volumes/projected/sources/secret/name
kind: StatefulSet
- path: spec/template/spec/volumes/secret/secretName
kind: Job
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: Job
- path: spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: Job
- path: spec/template/spec/containers/envFrom/secretRef/name
kind: Job
- path: spec/template/spec/initContainers/envFrom/secretRef/name
kind: Job
- path: spec/template/spec/imagePullSecrets/name
kind: Job
- path: spec/template/spec/volumes/projected/sources/secret/name
kind: Job
- path: spec/jobTemplate/spec/template/spec/volumes/secret/secretName
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/volumes/projected/sources/secret/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/env/valueFrom/secretKeyRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/envFrom/secretRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/envFrom/secretRef/name
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/imagePullSecrets/name
kind: CronJob
- path: spec/tls/secretName
kind: Ingress
- path: metadata/annotations/ingress.kubernetes.io\/auth-secret
kind: Ingress
- path: metadata/annotations/nginx.ingress.kubernetes.io\/auth-secret
kind: Ingress
- path: metadata/annotations/nginx.ingress.kubernetes.io\/auth-tls-secret
kind: Ingress
- path: imagePullSecrets/name
kind: ServiceAccount
- path: parameters/secretName
kind: StorageClass
- path: parameters/adminSecretName
kind: StorageClass
- path: parameters/userSecretName
kind: StorageClass
- path: parameters/secretRef
kind: StorageClass
- path: rules/resourceNames
kind: Role
- path: rules/resourceNames
kind: ClusterRole
- kind: Service
version: v1
fieldSpecs:
- path: spec/serviceName
kind: StatefulSet
group: apps
- path: spec/rules/http/paths/backend/serviceName
kind: Ingress
- path: spec/backend/serviceName
kind: Ingress
- path: spec/service/name
kind: APIService
group: apiregistration.k8s.io
- path: webhooks/clientConfig/service
kind: ValidatingWebhookConfiguration
group: admissionregistration.k8s.io
- path: webhooks/clientConfig/service
kind: MutatingWebhookConfiguration
group: admissionregistration.k8s.io
- kind: Role
group: rbac.authorization.k8s.io
fieldSpecs:
- path: roleRef/name
kind: RoleBinding
group: rbac.authorization.k8s.io
- kind: ClusterRole
group: rbac.authorization.k8s.io
fieldSpecs:
- path: roleRef/name
kind: RoleBinding
group: rbac.authorization.k8s.io
- path: roleRef/name
kind: ClusterRoleBinding
group: rbac.authorization.k8s.io
- kind: ServiceAccount
version: v1
fieldSpecs:
- path: subjects
kind: RoleBinding
group: rbac.authorization.k8s.io
- path: subjects
kind: ClusterRoleBinding
group: rbac.authorization.k8s.io
- path: spec/serviceAccountName
kind: Pod
- path: spec/template/spec/serviceAccountName
kind: StatefulSet
- path: spec/template/spec/serviceAccountName
kind: Deployment
- path: spec/template/spec/serviceAccountName
kind: ReplicationController
- path: spec/jobTemplate/spec/template/spec/serviceAccountName
kind: CronJob
- path: spec/template/spec/serviceAccountName
kind: Job
- path: spec/template/spec/serviceAccountName
kind: DaemonSet
- kind: PersistentVolumeClaim
version: v1
fieldSpecs:
- path: spec/volumes/persistentVolumeClaim/claimName
kind: Pod
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: StatefulSet
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: Deployment
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: ReplicationController
- path: spec/jobTemplate/spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: CronJob
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: Job
- path: spec/template/spec/volumes/persistentVolumeClaim/claimName
kind: DaemonSet
- kind: PersistentVolume
version: v1
fieldSpecs:
- path: spec/volumeName
kind: PersistentVolumeClaim
- path: rules/resourceNames
kind: ClusterRole
- kind: StorageClass
version: v1
group: storage.k8s.io
fieldSpecs:
- path: spec/storageClassName
kind: PersistentVolume
- path: spec/storageClassName
kind: PersistentVolumeClaim
- path: spec/volumeClaimTemplates/spec/storageClassName
kind: StatefulSet
`
)

View File

@@ -1,29 +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 defaultconfig
const (
namespaceFieldSpecs = `
namespace:
- path: metadata/namespace
create: true
- path: subjects
kind: RoleBinding
- path: subjects
kind: ClusterRoleBinding
`
)

View File

@@ -1,20 +0,0 @@
package defaultconfig
const replicasFieldSpecs = `
replicas:
- path: spec/replicas
create: true
kind: Deployment
- path: spec/replicas
create: true
kind: ReplicationController
- path: spec/replicas
create: true
kind: ReplicaSet
- path: spec/replicas
create: true
kind: StatefulSet
`

View File

@@ -1,207 +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 defaultconfig
const (
varReferenceFieldSpecs = `
varReference:
- path: spec/jobTemplate/spec/template/spec/containers/args
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/command
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/env/value
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/containers/volumeMounts/mountPath
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/args
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/command
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/env/value
kind: CronJob
- path: spec/jobTemplate/spec/template/spec/initContainers/volumeMounts/mountPath
kind: CronJob
- path: spec/template/spec/containers/args
kind: DaemonSet
- path: spec/template/spec/containers/command
kind: DaemonSet
- path: spec/template/spec/containers/env/value
kind: DaemonSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/initContainers/args
kind: DaemonSet
- path: spec/template/spec/initContainers/command
kind: DaemonSet
- path: spec/template/spec/initContainers/env/value
kind: DaemonSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: DaemonSet
- path: spec/template/spec/containers/args
kind: Deployment
- path: spec/template/spec/containers/command
kind: Deployment
- path: spec/template/spec/containers/env/value
kind: Deployment
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: Deployment
- path: spec/template/spec/initContainers/args
kind: Deployment
- path: spec/template/spec/initContainers/command
kind: Deployment
- path: spec/template/spec/initContainers/env/value
kind: Deployment
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: Deployment
- path: spec/rules/host
kind: Ingress
- path: spec/tls/hosts
kind: Ingress
- path: spec/tls/secretName
kind: Ingress
- path: spec/template/spec/containers/args
kind: Job
- path: spec/template/spec/containers/command
kind: Job
- path: spec/template/spec/containers/env/value
kind: Job
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: Job
- path: spec/template/spec/initContainers/args
kind: Job
- path: spec/template/spec/initContainers/command
kind: Job
- path: spec/template/spec/initContainers/env/value
kind: Job
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: Job
- path: spec/containers/args
kind: Pod
- path: spec/containers/command
kind: Pod
- path: spec/containers/env/value
kind: Pod
- path: spec/containers/volumeMounts/mountPath
kind: Pod
- path: spec/initContainers/args
kind: Pod
- path: spec/initContainers/command
kind: Pod
- path: spec/initContainers/env/value
kind: Pod
- path: spec/initContainers/volumeMounts/mountPath
kind: Pod
- path: spec/template/spec/containers/args
kind: ReplicaSet
- path: spec/template/spec/containers/command
kind: ReplicaSet
- path: spec/template/spec/containers/env/value
kind: ReplicaSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: ReplicaSet
- path: spec/template/spec/initContainers/args
kind: ReplicaSet
- path: spec/template/spec/initContainers/command
kind: ReplicaSet
- path: spec/template/spec/initContainers/env/value
kind: ReplicaSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: ReplicaSet
- path: spec/ports/port
kind: Service
- path: spec/ports/targetPort
kind: Service
- path: spec/template/spec/containers/args
kind: StatefulSet
- path: spec/template/spec/containers/command
kind: StatefulSet
- path: spec/template/spec/containers/env/value
kind: StatefulSet
- path: spec/template/spec/containers/volumeMounts/mountPath
kind: StatefulSet
- path: spec/template/spec/initContainers/args
kind: StatefulSet
- path: spec/template/spec/initContainers/command
kind: StatefulSet
- path: spec/template/spec/initContainers/env/value
kind: StatefulSet
- path: spec/template/spec/initContainers/volumeMounts/mountPath
kind: StatefulSet
- path: metadata/labels
`
)

View File

@@ -1,87 +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 (
"log"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
"sigs.k8s.io/yaml"
)
// Factory makes instances of TransformerConfig.
type Factory struct {
ldr ifc.Loader
}
// MakeTransformerConfig returns a merger of custom config,
// if any, with default config.
func MakeTransformerConfig(
ldr ifc.Loader, paths []string) (*TransformerConfig, error) {
t1 := MakeDefaultConfig()
if len(paths) == 0 {
return t1, nil
}
t2, err := NewFactory(ldr).FromFiles(paths)
if err != nil {
return nil, err
}
return t1.Merge(t2)
}
func NewFactory(l ifc.Loader) *Factory {
return &Factory{ldr: l}
}
func (tf *Factory) loader() ifc.Loader {
if tf.ldr.(ifc.Loader) == nil {
log.Fatal("no loader")
}
return tf.ldr
}
// FromFiles returns a TranformerConfig object from a list of files
func (tf *Factory) FromFiles(
paths []string) (*TransformerConfig, error) {
result := &TransformerConfig{}
for _, path := range paths {
data, err := tf.loader().Load(path)
if err != nil {
return nil, err
}
t, err := makeTransformerConfigFromBytes(data)
if err != nil {
return nil, err
}
result, err = result.Merge(t)
if err != nil {
return nil, err
}
}
return result, nil
}
// makeTransformerConfigFromBytes returns a TransformerConfig object from bytes
func makeTransformerConfigFromBytes(data []byte) (*TransformerConfig, error) {
var t TransformerConfig
err := yaml.Unmarshal(data, &t)
if err != nil {
return nil, err
}
t.sortFields()
return &t, nil
}

View File

@@ -1,43 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package config
import (
"reflect"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"testing"
"sigs.k8s.io/kustomize/v3/internal/loadertest"
)
func TestMakeDefaultConfig(t *testing.T) {
// Confirm default can be made without fatal error inside call.
_ = MakeDefaultConfig()
}
func TestFromFiles(t *testing.T) {
ldr := loadertest.NewFakeLoader("/app")
ldr.AddFile("/app/config.yaml", []byte(`
namePrefix:
- path: nameprefix/path
kind: SomeKind
`))
tcfg, err := NewFactory(ldr).FromFiles([]string{"/app/config.yaml"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
expected := &TransformerConfig{
NamePrefix: []types.FieldSpec{
{
Gvk: resid.Gvk{Kind: "SomeKind"},
Path: "nameprefix/path",
},
},
}
if !reflect.DeepEqual(tcfg, expected) {
t.Fatalf("expected %v\n but go6t %v\n", expected, tcfg)
}
}

View File

@@ -1,105 +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/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"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 {
resid.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
FieldSpecs types.FsSlice `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)"
}
type nbrSlice []NameBackReferences
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)
}
func (s nbrSlice) mergeAll(o nbrSlice) (result nbrSlice, err error) {
result = s
for _, r := range o {
result, err = result.mergeOne(r)
if err != nil {
return nil, err
}
}
return result, nil
}
func (s nbrSlice) mergeOne(other NameBackReferences) (nbrSlice, error) {
var result nbrSlice
var err error
found := false
for _, c := range s {
if c.Gvk.Equals(other.Gvk) {
c.FieldSpecs, err = c.FieldSpecs.MergeAll(other.FieldSpecs)
if err != nil {
return nil, err
}
found = true
}
result = append(result, c)
}
if !found {
result = append(result, other)
}
return result, nil
}

View File

@@ -1,109 +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 (
"reflect"
"sigs.k8s.io/kustomize/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"testing"
)
func TestMergeAll(t *testing.T) {
fsSlice1 := []types.FieldSpec{
{
Gvk: resid.Gvk{
Kind: "Pod",
},
Path: "path/to/a/name",
CreateIfNotPresent: false,
},
{
Gvk: resid.Gvk{
Kind: "Deployment",
},
Path: "another/path/to/some/name",
CreateIfNotPresent: false,
},
}
fsSlice2 := []types.FieldSpec{
{
Gvk: resid.Gvk{
Kind: "Job",
},
Path: "morepath/to/name",
CreateIfNotPresent: false,
},
{
Gvk: resid.Gvk{
Kind: "StatefulSet",
},
Path: "yet/another/path/to/a/name",
CreateIfNotPresent: false,
},
}
nbrsSlice1 := nbrSlice{
{
Gvk: resid.Gvk{
Kind: "ConfigMap",
},
FieldSpecs: fsSlice1,
},
{
Gvk: resid.Gvk{
Kind: "Secret",
},
FieldSpecs: fsSlice2,
},
}
nbrsSlice2 := nbrSlice{
{
Gvk: resid.Gvk{
Kind: "ConfigMap",
},
FieldSpecs: fsSlice1,
},
{
Gvk: resid.Gvk{
Kind: "Secret",
},
FieldSpecs: fsSlice2,
},
}
expected := nbrSlice{
{
Gvk: resid.Gvk{
Kind: "ConfigMap",
},
FieldSpecs: fsSlice1,
},
{
Gvk: resid.Gvk{
Kind: "Secret",
},
FieldSpecs: fsSlice2,
},
}
actual, err := nbrsSlice1.mergeAll(nbrsSlice2)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected\n %v\n but got\n %v\n", expected, actual)
}
}

View File

@@ -1,147 +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 provides the functions to load default or user provided configurations
// for different transformers
package config
import (
"log"
"sigs.k8s.io/kustomize/v3/api/types"
"sort"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config/defaultconfig"
)
// TransformerConfig holds the data needed to perform transformations.
type TransformerConfig struct {
NamePrefix types.FsSlice `json:"namePrefix,omitempty" yaml:"namePrefix,omitempty"`
NameSuffix types.FsSlice `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
NameSpace types.FsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
CommonLabels types.FsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
CommonAnnotations types.FsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
VarReference types.FsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
Images types.FsSlice `json:"images,omitempty" yaml:"images,omitempty"`
Replicas types.FsSlice `json:"replicas,omitempty" yaml:"replicas,omitempty"`
}
// MakeEmptyConfig returns an empty TransformerConfig object
func MakeEmptyConfig() *TransformerConfig {
return &TransformerConfig{}
}
// MakeDefaultConfig returns a default TransformerConfig.
func MakeDefaultConfig() *TransformerConfig {
c, err := makeTransformerConfigFromBytes(
defaultconfig.GetDefaultFieldSpecs())
if err != nil {
log.Fatalf("Unable to make default transformconfig: %v", err)
}
return c
}
// sortFields provides determinism in logging, tests, etc.
func (t *TransformerConfig) sortFields() {
sort.Sort(t.NamePrefix)
sort.Sort(t.NameSpace)
sort.Sort(t.CommonLabels)
sort.Sort(t.CommonAnnotations)
sort.Sort(t.NameReference)
sort.Sort(t.VarReference)
sort.Sort(t.Images)
sort.Sort(t.Replicas)
}
// AddPrefixFieldSpec adds a FieldSpec to NamePrefix
func (t *TransformerConfig) AddPrefixFieldSpec(fs types.FieldSpec) (err error) {
t.NamePrefix, err = t.NamePrefix.MergeOne(fs)
return err
}
// AddSuffixFieldSpec adds a FieldSpec to NameSuffix
func (t *TransformerConfig) AddSuffixFieldSpec(fs types.FieldSpec) (err error) {
t.NameSuffix, err = t.NameSuffix.MergeOne(fs)
return err
}
// AddLabelFieldSpec adds a FieldSpec to CommonLabels
func (t *TransformerConfig) AddLabelFieldSpec(fs types.FieldSpec) (err error) {
t.CommonLabels, err = t.CommonLabels.MergeOne(fs)
return err
}
// AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
func (t *TransformerConfig) AddAnnotationFieldSpec(fs types.FieldSpec) (err error) {
t.CommonAnnotations, err = t.CommonAnnotations.MergeOne(fs)
return err
}
// AddNamereferenceFieldSpec adds a NameBackReferences to NameReference
func (t *TransformerConfig) AddNamereferenceFieldSpec(
nbrs NameBackReferences) (err error) {
t.NameReference, err = t.NameReference.mergeOne(nbrs)
return err
}
// Merge merges two TransformerConfigs objects into
// a new TransformerConfig object
func (t *TransformerConfig) Merge(input *TransformerConfig) (
merged *TransformerConfig, err error) {
if input == nil {
return t, nil
}
merged = &TransformerConfig{}
merged.NamePrefix, err = t.NamePrefix.MergeAll(input.NamePrefix)
if err != nil {
return nil, err
}
merged.NameSuffix, err = t.NameSuffix.MergeAll(input.NameSuffix)
if err != nil {
return nil, err
}
merged.NameSpace, err = t.NameSpace.MergeAll(input.NameSpace)
if err != nil {
return nil, err
}
merged.CommonAnnotations, err = t.CommonAnnotations.MergeAll(
input.CommonAnnotations)
if err != nil {
return nil, err
}
merged.CommonLabels, err = t.CommonLabels.MergeAll(input.CommonLabels)
if err != nil {
return nil, err
}
merged.VarReference, err = t.VarReference.MergeAll(input.VarReference)
if err != nil {
return nil, err
}
merged.NameReference, err = t.NameReference.mergeAll(input.NameReference)
if err != nil {
return nil, err
}
merged.Images, err = t.Images.MergeAll(input.Images)
if err != nil {
return nil, err
}
merged.Replicas, err = t.Replicas.MergeAll(input.Replicas)
if err != nil {
return nil, err
}
merged.sortFields()
return merged, nil
}

View File

@@ -1,182 +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/v3/api/resid"
"sigs.k8s.io/kustomize/v3/api/types"
"testing"
"reflect"
)
func TestAddNamereferenceFieldSpec(t *testing.T) {
cfg := &TransformerConfig{}
nbrs := NameBackReferences{
Gvk: resid.Gvk{
Kind: "KindA",
},
FieldSpecs: []types.FieldSpec{
{
Gvk: resid.Gvk{
Kind: "KindB",
},
Path: "path/to/a/field",
CreateIfNotPresent: false,
},
},
}
err := cfg.AddNamereferenceFieldSpec(nbrs)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NameReference) != 1 {
t.Fatal("failed to add namereference FieldSpec")
}
}
func TestAddFieldSpecs(t *testing.T) {
cfg := &TransformerConfig{}
fieldSpec := types.FieldSpec{
Gvk: resid.Gvk{Group: "GroupA", Kind: "KindB"},
Path: "path/to/a/field",
CreateIfNotPresent: true,
}
err := cfg.AddPrefixFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NamePrefix) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
err = cfg.AddSuffixFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NameSuffix) != 1 {
t.Fatalf("failed to add namesuffix FieldSpec")
}
err = cfg.AddLabelFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.CommonLabels) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
err = cfg.AddAnnotationFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.CommonAnnotations) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
}
func TestMerge(t *testing.T) {
nameReference := []NameBackReferences{
{
Gvk: resid.Gvk{
Kind: "KindA",
},
FieldSpecs: []types.FieldSpec{
{
Gvk: resid.Gvk{
Kind: "KindB",
},
Path: "path/to/a/field",
CreateIfNotPresent: false,
},
},
},
{
Gvk: resid.Gvk{
Kind: "KindA",
},
FieldSpecs: []types.FieldSpec{
{
Gvk: resid.Gvk{
Kind: "KindC",
},
Path: "path/to/a/field",
CreateIfNotPresent: false,
},
},
},
}
fieldSpecs := []types.FieldSpec{
{
Gvk: resid.Gvk{Group: "GroupA", Kind: "KindB"},
Path: "path/to/a/field",
CreateIfNotPresent: true,
},
{
Gvk: resid.Gvk{Group: "GroupA", Kind: "KindC"},
Path: "path/to/a/field",
CreateIfNotPresent: true,
},
}
cfga := &TransformerConfig{}
cfga.AddNamereferenceFieldSpec(nameReference[0])
cfga.AddPrefixFieldSpec(fieldSpecs[0])
cfga.AddSuffixFieldSpec(fieldSpecs[0])
cfgb := &TransformerConfig{}
cfgb.AddNamereferenceFieldSpec(nameReference[1])
cfgb.AddPrefixFieldSpec(fieldSpecs[1])
cfga.AddSuffixFieldSpec(fieldSpecs[1])
actual, err := cfga.Merge(cfgb)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(actual.NamePrefix) != 2 {
t.Fatal("merge failed for namePrefix FieldSpec")
}
if len(actual.NameSuffix) != 2 {
t.Fatal("merge failed for nameSuffix FieldSpec")
}
if len(actual.NameReference) != 1 {
t.Fatal("merge failed for namereference FieldSpec")
}
expected := &TransformerConfig{}
expected.AddNamereferenceFieldSpec(nameReference[0])
expected.AddNamereferenceFieldSpec(nameReference[1])
expected.AddPrefixFieldSpec(fieldSpecs[0])
expected.AddPrefixFieldSpec(fieldSpecs[1])
expected.AddSuffixFieldSpec(fieldSpecs[0])
expected.AddSuffixFieldSpec(fieldSpecs[1])
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected: %v\n but got: %v\n", expected, actual)
}
actual, err = cfga.Merge(nil)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(actual, cfga) {
t.Fatalf("expected: %v\n but got: %v\n", cfga, actual)
}
}

View File

@@ -1,9 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Utilities to aid transformer plugins.
//
// TODO: Push remaining code down into the plugins
// or into an appropriately named utility package.
// This package made more sense in the pre-plugin days.
package transformers

View File

@@ -1,89 +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 transformers
import (
"errors"
"fmt"
"sigs.k8s.io/kustomize/v3/api/types"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
)
// mapTransformer applies a string->string map to fieldSpecs.
type mapTransformer struct {
m map[string]string
fieldSpecs []types.FieldSpec
}
var _ resmap.Transformer = &mapTransformer{}
// NewLabelsMapTransformer constructs a mapTransformer.
func NewLabelsMapTransformer(
m map[string]string, fs []types.FieldSpec) (resmap.Transformer, error) {
return NewMapTransformer(fs, m)
}
// NewAnnotationsMapTransformer construct a mapTransformer.
func NewAnnotationsMapTransformer(
m map[string]string, fs []types.FieldSpec) (resmap.Transformer, error) {
return NewMapTransformer(fs, m)
}
// NewMapTransformer construct a mapTransformer.
func NewMapTransformer(
pc []types.FieldSpec, m map[string]string) (resmap.Transformer, error) {
if m == nil {
return NewNoOpTransformer(), nil
}
if pc == nil {
return nil, errors.New("fieldSpecs is not expected to be nil")
}
return &mapTransformer{fieldSpecs: pc, m: m}, nil
}
// Transform apply each <key, value> pair in the mapTransformer to the
// fields specified in mapTransformer.
func (o *mapTransformer) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() {
for _, path := range o.fieldSpecs {
if !r.OrgId().IsSelected(&path.Gvk) {
continue
}
err := MutateField(
r.Map(), path.PathSlice(),
path.CreateIfNotPresent, o.addMap)
if err != nil {
return err
}
}
}
return nil
}
func (o *mapTransformer) addMap(in interface{}) (interface{}, error) {
m, ok := in.(map[string]interface{})
if in == nil {
m = map[string]interface{}{}
} else if !ok {
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
}
for k, v := range o.m {
m[k] = v
}
return m, nil
}

View File

@@ -1,570 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package transformers
import (
"testing"
"sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/v3/pkg/resmaptest"
"sigs.k8s.io/kustomize/v3/pkg/resource"
"sigs.k8s.io/kustomize/v3/pkg/transformers/config"
)
var rf = resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
var defaultTransformerConfig = config.MakeDefaultConfig()
func TestLabelsRun(t *testing.T) {
m := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
}).
Add(map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"old-label": "old-value",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
"metadata": map[string]interface{}{
"name": "svc1",
},
"spec": map[string]interface{}{
"ports": []interface{}{
map[string]interface{}{
"name": "port1",
"port": "12345",
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": map[string]interface{}{
"name": "job1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": map[string]interface{}{
"name": "job2",
},
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"old-label": "old-value",
},
},
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1beta1",
"kind": "CronJob",
"metadata": map[string]interface{}{
"name": "cronjob1",
},
"spec": map[string]interface{}{
"schedule": "* 23 * * *",
"jobTemplate": map[string]interface{}{
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1beta1",
"kind": "CronJob",
"metadata": map[string]interface{}{
"name": "cronjob2",
},
"spec": map[string]interface{}{
"schedule": "* 23 * * *",
"jobTemplate": map[string]interface{}{
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"old-label": "old-value",
},
},
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
},
},
}).ResMap()
expected := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
}).
Add(map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"old-label": "old-value",
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
"metadata": map[string]interface{}{
"name": "svc1",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"ports": []interface{}{
map[string]interface{}{
"name": "port1",
"port": "12345",
},
},
"selector": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": map[string]interface{}{
"name": "job1",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": map[string]interface{}{
"name": "job2",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
"old-label": "old-value",
},
},
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1beta1",
"kind": "CronJob",
"metadata": map[string]interface{}{
"name": "cronjob1",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"schedule": "* 23 * * *",
"jobTemplate": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "batch/v1beta1",
"kind": "CronJob",
"metadata": map[string]interface{}{
"name": "cronjob2",
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"schedule": "* 23 * * *",
"jobTemplate": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"selector": map[string]interface{}{
"matchLabels": map[string]interface{}{
"old-label": "old-value",
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"label-key1": "label-value1",
"label-key2": "label-value2",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
},
},
}).ResMap()
lt, err := NewLabelsMapTransformer(
map[string]string{"label-key1": "label-value1", "label-key2": "label-value2"},
defaultTransformerConfig.CommonLabels)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = lt.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestAnnotationsRun(t *testing.T) {
m := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
}).
Add(map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"old-label": "old-value",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
"metadata": map[string]interface{}{
"name": "svc1",
},
"spec": map[string]interface{}{
"ports": []interface{}{
map[string]interface{}{
"name": "port1",
"port": "12345",
},
},
},
}).ResMap()
expected := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
"annotations": map[string]interface{}{
"anno-key1": "anno-value1",
"anno-key2": "anno-value2",
},
},
}).
Add(map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deploy1",
"annotations": map[string]interface{}{
"anno-key1": "anno-value1",
"anno-key2": "anno-value2",
},
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"anno-key1": "anno-value1",
"anno-key2": "anno-value2",
},
"labels": map[string]interface{}{
"old-label": "old-value",
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "nginx",
"image": "nginx:1.7.9",
},
},
},
},
},
}).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "Service",
"metadata": map[string]interface{}{
"name": "svc1",
"annotations": map[string]interface{}{
"anno-key1": "anno-value1",
"anno-key2": "anno-value2",
},
},
"spec": map[string]interface{}{
"ports": []interface{}{
map[string]interface{}{
"name": "port1",
"port": "12345",
},
},
},
}).ResMap()
at, err := NewAnnotationsMapTransformer(
map[string]string{"anno-key1": "anno-value1", "anno-key2": "anno-value2"},
defaultTransformerConfig.CommonAnnotations)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = at.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
}
func TestAnnotationsRunWithNullValue(t *testing.T) {
m := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
"annotations": nil,
},
}).ResMap()
expected := resmaptest_test.NewRmBuilder(t, rf).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
"annotations": map[string]interface{}{
"anno-key1": "anno-value1",
"anno-key2": "anno-value2",
},
},
}).ResMap()
at, err := NewAnnotationsMapTransformer(
map[string]string{"anno-key1": "anno-value1", "anno-key2": "anno-value2"},
defaultTransformerConfig.CommonAnnotations)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
err = at.Transform(m)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err = expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf("actual doesn't match expected: %v", err)
}
}

View File

@@ -1,84 +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 transformers
import (
"fmt"
"sigs.k8s.io/kustomize/v3/pkg/resmap"
)
// multiTransformer contains a list of transformers.
type multiTransformer struct {
transformers []resmap.Transformer
checkConflictEnabled bool
}
var _ resmap.Transformer = &multiTransformer{}
// NewMultiTransformer constructs a multiTransformer.
func NewMultiTransformer(t []resmap.Transformer) resmap.Transformer {
r := &multiTransformer{
transformers: make([]resmap.Transformer, len(t)),
checkConflictEnabled: false}
copy(r.transformers, t)
return r
}
// Transform prepends the name prefix.
func (o *multiTransformer) Transform(m resmap.ResMap) error {
if o.checkConflictEnabled {
return o.transformWithCheckConflict(m)
}
return o.transform(m)
}
func (o *multiTransformer) transform(m resmap.ResMap) error {
for _, t := range o.transformers {
err := t.Transform(m)
if err != nil {
return err
}
}
return nil
}
// Of the len(o.transformers)! possible transformer orderings, compare to a reversed order.
// A spot check to perform when the transformations are supposed to be commutative.
// Fail if there's a difference in the result.
func (o *multiTransformer) transformWithCheckConflict(m resmap.ResMap) error {
mcopy := m.DeepCopy()
err := o.transform(m)
if err != nil {
return err
}
o.reverseTransformers()
err = o.transform(mcopy)
if err != nil {
return err
}
err = m.ErrorIfNotEqualSets(mcopy)
if err != nil {
return fmt.Errorf("found conflict between different patches\n%v", err)
}
return nil
}
func (o *multiTransformer) reverseTransformers() {
for i, j := 0, len(o.transformers)-1; i < j; i, j = i+1, j-1 {
o.transformers[i], o.transformers[j] = o.transformers[j], o.transformers[i]
}
}

View File

@@ -1,90 +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 transformers
import (
"fmt"
"log"
"strings"
)
type mutateFunc func(interface{}) (interface{}, error)
func MutateField(
m map[string]interface{},
pathToField []string,
createIfNotPresent bool,
fns ...mutateFunc) error {
if len(pathToField) == 0 {
return nil
}
firstPathSegment, isArray := getFirstPathSegment(pathToField)
_, found := m[firstPathSegment]
if !found {
if !createIfNotPresent || isArray {
return nil
}
m[firstPathSegment] = map[string]interface{}{}
}
if len(pathToField) == 1 {
var err error
for _, fn := range fns {
m[firstPathSegment], err = fn(m[firstPathSegment])
if err != nil {
return err
}
}
return nil
}
v := m[firstPathSegment]
newPathToField := pathToField[1:]
switch typedV := v.(type) {
case nil:
log.Printf(
"nil value at `%s` ignored in mutation attempt",
strings.Join(pathToField, "."))
return nil
case map[string]interface{}:
return MutateField(typedV, newPathToField, createIfNotPresent, fns...)
case []interface{}:
for i := range typedV {
item := typedV[i]
typedItem, ok := item.(map[string]interface{})
if !ok {
return fmt.Errorf("%#v is expected to be %T", item, typedItem)
}
err := MutateField(typedItem, newPathToField, createIfNotPresent, fns...)
if err != nil {
return err
}
}
return nil
default:
return fmt.Errorf("%#v is not expected to be a primitive type", typedV)
}
}
func getFirstPathSegment(pathToField []string) (string, bool) {
if strings.HasSuffix(pathToField[0], "[]") {
return pathToField[0][:len(pathToField[0])-2], true
}
return pathToField[0], false
}

View File

@@ -1,169 +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 transformers
import (
"fmt"
"testing"
"sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/v3/pkg/ifc"
)
type noopMutator struct {
wasCalled bool
errorToReturn error
}
var errExpected = fmt.Errorf("oops")
const originalValue = "tomato"
const newValue = "notThe" + originalValue
func (m *noopMutator) mutate(in interface{}) (interface{}, error) {
m.wasCalled = true
return newValue, m.errorToReturn
}
func makeTestDeployment() ifc.Kunstructured {
factory := kunstruct.NewKunstructuredFactoryImpl()
return factory.FromMap(
map[string]interface{}{
"group": "apps",
"apiVersion": "v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": originalValue,
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"env": []interface{}{
map[string]interface{}{
"name": "HELLO",
"value": "hi there",
},
map[string]interface{}{
"name": "GOODBYE",
"value": "adios!",
},
},
"metadata": map[string]interface{}{
"labels": map[string]interface{}{
"vegetable": originalValue,
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "tangerine",
"image": originalValue,
},
},
},
},
},
})
}
func getFieldValue(t *testing.T, obj ifc.Kunstructured, fieldName string) string {
v, err := obj.GetString(fieldName)
if err != nil {
t.Fatalf("unexpected field error: %v", err)
}
return v
}
func TestNoPath(t *testing.T) {
obj := makeTestDeployment()
m := &noopMutator{}
err := MutateField(
obj.Map(), []string{}, false, m.mutate)
if m.wasCalled {
t.Fatalf("mutator should not have been called.")
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestHappyPath(t *testing.T) {
obj := makeTestDeployment()
v := getFieldValue(t, obj, "metadata.name")
if v != originalValue {
t.Fatalf("unexpected original value: %v", v)
}
v = getFieldValue(t, obj, "spec.template.metadata.labels.vegetable")
if v != originalValue {
t.Fatalf("unexpected original value: %v", v)
}
m := &noopMutator{}
err := MutateField(
obj.Map(), []string{"metadata", "name"}, false, m.mutate)
if !m.wasCalled {
t.Fatalf("mutator should have been called.")
}
if err != nil {
t.Fatalf("unexpected mutate error: %v", err)
}
v = getFieldValue(t, obj, "metadata.name")
if v != newValue {
t.Fatalf("unexpected new value: %v", v)
}
m = &noopMutator{}
err = MutateField(
obj.Map(), []string{"spec", "template", "metadata", "labels", "vegetable"}, false, m.mutate)
if !m.wasCalled {
t.Fatalf("mutator should have been called.")
}
if err != nil {
t.Fatalf("unexpected mutate error: %v", err)
}
v = getFieldValue(t, obj, "spec.template.metadata.labels.vegetable")
if v != newValue {
t.Fatalf("unexpected new value: %v", v)
}
}
func TestWithError(t *testing.T) {
obj := makeTestDeployment()
m := noopMutator{errorToReturn: errExpected}
err := MutateField(
obj.Map(), []string{"metadata", "name"}, false, m.mutate)
if !m.wasCalled {
t.Fatalf("mutator was not called!")
}
if err != errExpected {
t.Fatalf("unexpected error: %v", err)
}
}
func TestWithNil(t *testing.T) {
obj := makeTestDeployment()
foo := obj.Map()["spec"]
foo = foo.(map[string]interface{})["template"]
foo = foo.(map[string]interface{})["metadata"]
foo.(map[string]interface{})["labels"] = nil
m := &noopMutator{}
err := MutateField(
obj.Map(), []string{"spec", "template", "metadata", "labels", "vegetable"}, false, m.mutate)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
}

View File

@@ -1,34 +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 transformers
import "sigs.k8s.io/kustomize/v3/pkg/resmap"
// noOpTransformer contains a no-op transformer.
type noOpTransformer struct{}
var _ resmap.Transformer = &noOpTransformer{}
// NewNoOpTransformer constructs a noOpTransformer.
func NewNoOpTransformer() resmap.Transformer {
return &noOpTransformer{}
}
// Transform does nothing.
func (o *noOpTransformer) Transform(_ resmap.ResMap) error {
return nil
}