mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-14 02:20:53 +00:00
Drain pkg/transformers.
This commit is contained in:
@@ -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))},
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
`
|
||||
@@ -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
|
||||
`
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 = ``
|
||||
)
|
||||
@@ -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
|
||||
`
|
||||
)
|
||||
@@ -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
|
||||
`
|
||||
)
|
||||
@@ -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
|
||||
`
|
||||
)
|
||||
@@ -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
|
||||
`
|
||||
@@ -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
|
||||
`
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user