mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-29 17:41:13 +00:00
add replacement transformer
This commit is contained in:
65
api/builtins/ReplacementTransformer.go
Normal file
65
api/builtins/ReplacementTransformer.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Code generated by pluginator on ReplacementTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
|
||||
package builtins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/filters/replacement"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// Replace values in targets with values from a source
|
||||
type ReplacementTransformerPlugin struct {
|
||||
ReplacementList []types.ReplacementField `json:"replacements,omitempty" yaml:"replacements,omitempty"`
|
||||
Replacements []types.Replacement `json:"omitempty" yaml:"omitempty"`
|
||||
}
|
||||
|
||||
func (p *ReplacementTransformerPlugin) Config(
|
||||
h *resmap.PluginHelpers, c []byte) (err error) {
|
||||
p.ReplacementList = []types.ReplacementField{}
|
||||
if err := yaml.Unmarshal(c, p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, r := range p.ReplacementList {
|
||||
if r.Path != "" && (r.Source != nil || len(r.Targets) != 0) {
|
||||
return fmt.Errorf("cannot specify both path and inline replacement")
|
||||
}
|
||||
if r.Path != "" {
|
||||
// load the replacement from the path
|
||||
content, err := h.Loader().Load(r.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repl := types.Replacement{}
|
||||
if err := yaml.Unmarshal(content, &repl); err != nil {
|
||||
return err
|
||||
}
|
||||
p.Replacements = append(p.Replacements, repl)
|
||||
} else {
|
||||
// replacement information is already loaded
|
||||
p.Replacements = append(p.Replacements, r.Replacement)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ReplacementTransformerPlugin) Transform(m resmap.ResMap) (err error) {
|
||||
var nodes []*kyaml.RNode
|
||||
for _, r := range m.Resources() {
|
||||
nodes = append(nodes, r.Node())
|
||||
}
|
||||
_, err = replacement.Filter{
|
||||
Replacements: p.Replacements,
|
||||
}.Filter(nodes)
|
||||
return err
|
||||
}
|
||||
|
||||
func NewReplacementTransformerPlugin() resmap.TransformerPlugin {
|
||||
return &ReplacementTransformerPlugin{}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type Filter struct {
|
||||
Replacements []types.Replacement
|
||||
Replacements []types.Replacement `json:"replacements,omitempty" yaml:"replacements,omitempty"`
|
||||
}
|
||||
|
||||
// Filter replaces values of targets with values from sources
|
||||
|
||||
@@ -24,11 +24,12 @@ func _() {
|
||||
_ = x[SecretGenerator-13]
|
||||
_ = x[ValueAddTransformer-14]
|
||||
_ = x[HelmChartInflationGenerator-15]
|
||||
_ = x[ReplacementTransformer-16]
|
||||
}
|
||||
|
||||
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGenerator"
|
||||
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer"
|
||||
|
||||
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289, 316}
|
||||
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289, 316, 338}
|
||||
|
||||
func (i BuiltinPluginType) String() string {
|
||||
if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) {
|
||||
|
||||
@@ -28,6 +28,7 @@ const (
|
||||
SecretGenerator
|
||||
ValueAddTransformer
|
||||
HelmChartInflationGenerator
|
||||
ReplacementTransformer
|
||||
)
|
||||
|
||||
var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType
|
||||
@@ -72,6 +73,7 @@ var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin
|
||||
PatchStrategicMergeTransformer: builtins.NewPatchStrategicMergeTransformerPlugin,
|
||||
PatchTransformer: builtins.NewPatchTransformerPlugin,
|
||||
PrefixSuffixTransformer: builtins.NewPrefixSuffixTransformerPlugin,
|
||||
ReplacementTransformer: builtins.NewReplacementTransformerPlugin,
|
||||
ReplicaCountTransformer: builtins.NewReplicaCountTransformerPlugin,
|
||||
ValueAddTransformer: builtins.NewValueAddTransformerPlugin,
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ func (kt *KustTarget) configureBuiltinTransformers(
|
||||
builtinhelpers.PatchJson6902Transformer,
|
||||
builtinhelpers.ReplicaCountTransformer,
|
||||
builtinhelpers.ImageTagTransformer,
|
||||
builtinhelpers.ReplacementTransformer,
|
||||
} {
|
||||
r, err := transformerConfigurators[bpt](
|
||||
kt, bpt, builtinhelpers.TransformerFactories[bpt], tc)
|
||||
@@ -323,6 +324,21 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
|
||||
}
|
||||
return
|
||||
},
|
||||
builtinhelpers.ReplacementTransformer: func(
|
||||
kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, _ *builtinconfig.TransformerConfig) (
|
||||
result []resmap.Transformer, err error) {
|
||||
var c struct {
|
||||
Replacements []types.ReplacementField
|
||||
}
|
||||
c.Replacements = kt.kustomization.Replacements
|
||||
p := f()
|
||||
err = kt.configureBuiltinPlugin(p, c, bpt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, p)
|
||||
return result, nil
|
||||
},
|
||||
builtinhelpers.ReplicaCountTransformer: func(
|
||||
kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
|
||||
result []resmap.Transformer, err error) {
|
||||
|
||||
271
api/krusty/replacementtransformer_test.go
Normal file
271
api/krusty/replacementtransformer_test.go
Normal file
@@ -0,0 +1,271 @@
|
||||
package krusty_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
// end to end tests to demonstrate functionality of ReplacementTransformer
|
||||
func TestReplacementsField(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarness(t)
|
||||
defer th.Reset()
|
||||
|
||||
th.WriteK(".", `
|
||||
resources:
|
||||
- resource.yaml
|
||||
|
||||
replacements:
|
||||
- source:
|
||||
kind: Deployment
|
||||
fieldPath: spec.template.spec.containers.0.image
|
||||
targets:
|
||||
- select:
|
||||
kind: Deployment
|
||||
fieldPaths:
|
||||
- spec.template.spec.containers.1.image
|
||||
`)
|
||||
th.WriteF("resource.yaml", `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: postgres:1.8.0
|
||||
name: postgresdb
|
||||
`)
|
||||
expected := `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: foobar:1
|
||||
name: postgresdb
|
||||
`
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, expected)
|
||||
}
|
||||
|
||||
func TestReplacementsFieldWithPath(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarness(t)
|
||||
defer th.Reset()
|
||||
|
||||
th.WriteK(".", `
|
||||
resources:
|
||||
- resource.yaml
|
||||
|
||||
replacements:
|
||||
- path: replacement.yaml
|
||||
`)
|
||||
th.WriteF("replacement.yaml",
|
||||
`
|
||||
source:
|
||||
kind: Deployment
|
||||
fieldPath: spec.template.spec.containers.0.image
|
||||
targets:
|
||||
- select:
|
||||
kind: Deployment
|
||||
fieldPaths:
|
||||
- spec.template.spec.containers.1.image
|
||||
`)
|
||||
th.WriteF("resource.yaml", `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: postgres:1.8.0
|
||||
name: postgresdb
|
||||
`)
|
||||
expected := `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: foobar:1
|
||||
name: replaced-with-digest
|
||||
- image: foobar:1
|
||||
name: postgresdb
|
||||
`
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, expected)
|
||||
}
|
||||
|
||||
func TestReplacementTransformerWithDiamondShape(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarness(t)
|
||||
defer th.Reset()
|
||||
|
||||
th.WriteF("base/deployment.yaml",
|
||||
`
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:1.7.9
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sourceA
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagA
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sourceB
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagB
|
||||
name: nginx
|
||||
`)
|
||||
th.WriteF("base/kustomization.yaml",
|
||||
`
|
||||
resources:
|
||||
- deployment.yaml
|
||||
`)
|
||||
th.WriteF("a/kustomization.yaml",
|
||||
`
|
||||
namePrefix: a-
|
||||
resources:
|
||||
- ../base
|
||||
replacements:
|
||||
- path: replacement.yaml
|
||||
`)
|
||||
th.WriteF("a/replacement.yaml",
|
||||
`
|
||||
source:
|
||||
name: a-sourceA
|
||||
fieldPath: spec.template.spec.containers.0.image
|
||||
targets:
|
||||
- select:
|
||||
name: a-deploy
|
||||
fieldPaths:
|
||||
- spec.template.spec.containers.[name=nginx].image
|
||||
`)
|
||||
th.WriteF("b/kustomization.yaml",
|
||||
`
|
||||
namePrefix: b-
|
||||
resources:
|
||||
- ../base
|
||||
replacements:
|
||||
- path: replacement.yaml
|
||||
`)
|
||||
th.WriteF("b/replacement.yaml",
|
||||
`
|
||||
source:
|
||||
name: b-sourceB
|
||||
fieldPath: spec.template.spec.containers.0.image
|
||||
targets:
|
||||
- select:
|
||||
name: b-deploy
|
||||
fieldPaths:
|
||||
- spec.template.spec.containers.[name=nginx].image
|
||||
`)
|
||||
th.WriteF("combined/kustomization.yaml",
|
||||
`
|
||||
resources:
|
||||
- ../a
|
||||
- ../b
|
||||
`)
|
||||
|
||||
m := th.Run("combined", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: a-deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagA
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: a-sourceA
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagA
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: a-sourceB
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagB
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: b-deploy
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagB
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: b-sourceA
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagA
|
||||
name: nginx
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: b-sourceB
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:newtagB
|
||||
name: nginx
|
||||
`)
|
||||
}
|
||||
@@ -57,6 +57,10 @@ func (r *Resource) AsRNode() *kyaml.RNode {
|
||||
return r.node.Copy()
|
||||
}
|
||||
|
||||
func (r *Resource) Node() *kyaml.RNode {
|
||||
return r.node
|
||||
}
|
||||
|
||||
func (r *Resource) ResetPrimaryData(incoming *Resource) {
|
||||
r.node = incoming.node.Copy()
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ type Kustomization struct {
|
||||
// patch, but this operator is simpler to specify.
|
||||
Images []Image `json:"images,omitempty" yaml:"images,omitempty"`
|
||||
|
||||
// Replacements is a list of replacements, which will copy nodes from a
|
||||
// specified source to N specified targets.
|
||||
Replacements []ReplacementField `json:"replacements,omitempty" yaml:"replacements,omitempty"`
|
||||
|
||||
// Replicas is a list of {resourcename, count} that allows for simpler replica
|
||||
// specification. This can also be done with a patch.
|
||||
Replicas []Replica `json:"replicas,omitempty" yaml:"replicas,omitempty"`
|
||||
|
||||
6
api/types/replacementfield.go
Normal file
6
api/types/replacementfield.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package types
|
||||
|
||||
type ReplacementField struct {
|
||||
Replacement `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user