mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Switch prefix transformer to kyaml.
This commit is contained in:
@@ -6,7 +6,8 @@ package builtins
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/transform"
|
"sigs.k8s.io/kustomize/api/filters/replicacount"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/filtersutil"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/resid"
|
"sigs.k8s.io/kustomize/api/resid"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
@@ -30,21 +31,27 @@ func (p *ReplicaCountTransformerPlugin) Config(
|
|||||||
|
|
||||||
func (p *ReplicaCountTransformerPlugin) Transform(m resmap.ResMap) error {
|
func (p *ReplicaCountTransformerPlugin) Transform(m resmap.ResMap) error {
|
||||||
found := false
|
found := false
|
||||||
for i, replicaSpec := range p.FieldSpecs {
|
for _, fs := range p.FieldSpecs {
|
||||||
matcher := p.createMatcher(i)
|
matcher := p.createMatcher(fs)
|
||||||
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
||||||
matchCurrent := m.GetMatchingResourcesByCurrentId(matcher)
|
resList := append(
|
||||||
|
matchOriginal, m.GetMatchingResourcesByCurrentId(matcher)...)
|
||||||
for _, res := range append(matchOriginal, matchCurrent...) {
|
if len(resList) > 0 {
|
||||||
found = true
|
found = true
|
||||||
err := transform.MutateField(
|
for _, r := range resList {
|
||||||
res.Map(), replicaSpec.PathSlice(),
|
// There are redundant checks in the filter
|
||||||
replicaSpec.CreateIfNotPresent, p.addReplicas)
|
// that we'll live with until resolution of
|
||||||
|
// https://github.com/kubernetes-sigs/kustomize/issues/2506
|
||||||
|
err := filtersutil.ApplyToJSON(replicacount.Filter{
|
||||||
|
Replica: p.Replica,
|
||||||
|
FieldSpec: fs,
|
||||||
|
}, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
gvks := make([]string, len(p.FieldSpecs))
|
gvks := make([]string, len(p.FieldSpecs))
|
||||||
@@ -59,30 +66,12 @@ func (p *ReplicaCountTransformerPlugin) Transform(m resmap.ResMap) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Match Replica.Name and FieldSpec
|
// Match Replica.Name and FieldSpec
|
||||||
func (p *ReplicaCountTransformerPlugin) createMatcher(i int) resmap.IdMatcher {
|
func (p *ReplicaCountTransformerPlugin) createMatcher(fs types.FieldSpec) resmap.IdMatcher {
|
||||||
return func(r resid.ResId) bool {
|
return func(r resid.ResId) bool {
|
||||||
return r.Name == p.Replica.Name &&
|
return r.Name == p.Replica.Name && r.Gvk.IsSelected(&fs.Gvk)
|
||||||
r.Gvk.IsSelected(&p.FieldSpecs[i].Gvk)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ReplicaCountTransformerPlugin) addReplicas(in interface{}) (interface{}, error) {
|
|
||||||
switch m := in.(type) {
|
|
||||||
case int64:
|
|
||||||
// Was already in the field.
|
|
||||||
case map[string]interface{}:
|
|
||||||
if len(m) != 0 {
|
|
||||||
// A map was already in the replicas field, don't want to
|
|
||||||
// discard this data silently.
|
|
||||||
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
|
|
||||||
}
|
|
||||||
// Just got added, default type is map, but we can return anything.
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
|
|
||||||
}
|
|
||||||
return p.Replica.Count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReplicaCountTransformerPlugin() resmap.TransformerPlugin {
|
func NewReplicaCountTransformerPlugin() resmap.TransformerPlugin {
|
||||||
return &ReplicaCountTransformerPlugin{}
|
return &ReplicaCountTransformerPlugin{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,9 @@ spec:
|
|||||||
Count: 42,
|
Count: 42,
|
||||||
Name: "instance",
|
Name: "instance",
|
||||||
},
|
},
|
||||||
FsSlice: types.FsSlice{
|
FieldSpec: types.FieldSpec{
|
||||||
{
|
|
||||||
Path: "spec/template/replicas",
|
Path: "spec/template/replicas",
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}},
|
}},
|
||||||
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
|
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
|
||||||
}.Execute()
|
}.Execute()
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package replicacount
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/api/filters/fieldspec"
|
||||||
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
||||||
"sigs.k8s.io/kustomize/api/filters/fsslice"
|
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
@@ -13,9 +13,7 @@ import (
|
|||||||
// Filter updates/sets replicas fields using the fieldSpecs
|
// Filter updates/sets replicas fields using the fieldSpecs
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
Replica types.Replica `json:"replica,omitempty" yaml:"replica,omitempty"`
|
Replica types.Replica `json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||||
|
FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"`
|
||||||
// FsSlice contains the FieldSpecs to locate the namespace field
|
|
||||||
FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ kio.Filter = Filter{}
|
var _ kio.Filter = Filter{}
|
||||||
@@ -24,20 +22,9 @@ func (rc Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
|||||||
return kio.FilterAll(yaml.FilterFunc(rc.run)).Filter(nodes)
|
return kio.FilterAll(yaml.FilterFunc(rc.run)).Filter(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// run processes each node individually.
|
|
||||||
func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
||||||
meta, err := node.GetMeta()
|
err := node.PipeE(fieldspec.Filter{
|
||||||
if err != nil {
|
FieldSpec: rc.FieldSpec,
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// only update resources where the name matches the Replica name.
|
|
||||||
if meta.Name != rc.Replica.Name {
|
|
||||||
return node, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = node.PipeE(fsslice.Filter{
|
|
||||||
FsSlice: rc.FsSlice,
|
|
||||||
SetValue: rc.set,
|
SetValue: rc.set,
|
||||||
CreateKind: yaml.ScalarNode, // replicas is a ScalarNode
|
CreateKind: yaml.ScalarNode, // replicas is a ScalarNode
|
||||||
CreateTag: yaml.IntTag,
|
CreateTag: yaml.IntTag,
|
||||||
|
|||||||
@@ -5,19 +5,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
|
||||||
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
|
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
func TestFilter(t *testing.T) {
|
||||||
var config = builtinconfig.MakeDefaultConfig()
|
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
input string
|
input string
|
||||||
expected string
|
expected string
|
||||||
filter Filter
|
filter Filter
|
||||||
fsslice types.FsSlice
|
|
||||||
}{
|
}{
|
||||||
"update field": {
|
"update field": {
|
||||||
input: `
|
input: `
|
||||||
@@ -41,11 +38,7 @@ spec:
|
|||||||
Name: "dep",
|
Name: "dep",
|
||||||
Count: 42,
|
Count: 42,
|
||||||
},
|
},
|
||||||
},
|
FieldSpec: types.FieldSpec{Path: "spec/replicas"},
|
||||||
fsslice: types.FsSlice{
|
|
||||||
{
|
|
||||||
Path: "spec/replicas",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"add field": {
|
"add field": {
|
||||||
@@ -73,9 +66,7 @@ spec:
|
|||||||
Name: "cus",
|
Name: "cus",
|
||||||
Count: 42,
|
Count: 42,
|
||||||
},
|
},
|
||||||
},
|
FieldSpec: types.FieldSpec{
|
||||||
fsslice: types.FsSlice{
|
|
||||||
{
|
|
||||||
Path: "spec/template/replicas",
|
Path: "spec/template/replicas",
|
||||||
CreateIfNotPresent: true,
|
CreateIfNotPresent: true,
|
||||||
},
|
},
|
||||||
@@ -108,9 +99,7 @@ spec:
|
|||||||
Name: "cus",
|
Name: "cus",
|
||||||
Count: 42,
|
Count: 42,
|
||||||
},
|
},
|
||||||
},
|
FieldSpec: types.FieldSpec{
|
||||||
fsslice: types.FsSlice{
|
|
||||||
{
|
|
||||||
Path: "spec/template/replicas",
|
Path: "spec/template/replicas",
|
||||||
CreateIfNotPresent: true,
|
CreateIfNotPresent: true,
|
||||||
},
|
},
|
||||||
@@ -140,9 +129,7 @@ spec:
|
|||||||
Name: "cus",
|
Name: "cus",
|
||||||
Count: 42,
|
Count: 42,
|
||||||
},
|
},
|
||||||
},
|
FieldSpec: types.FieldSpec{
|
||||||
fsslice: types.FsSlice{
|
|
||||||
{
|
|
||||||
Path: "spec/template/replicas",
|
Path: "spec/template/replicas",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -154,7 +141,6 @@ kind: Custom
|
|||||||
metadata:
|
metadata:
|
||||||
name: cus
|
name: cus
|
||||||
spec:
|
spec:
|
||||||
replicas: 5
|
|
||||||
template:
|
template:
|
||||||
replicas: 5
|
replicas: 5
|
||||||
`,
|
`,
|
||||||
@@ -164,7 +150,6 @@ kind: Custom
|
|||||||
metadata:
|
metadata:
|
||||||
name: cus
|
name: cus
|
||||||
spec:
|
spec:
|
||||||
replicas: 42
|
|
||||||
template:
|
template:
|
||||||
replicas: 42
|
replicas: 42
|
||||||
`,
|
`,
|
||||||
@@ -173,21 +158,13 @@ spec:
|
|||||||
Name: "cus",
|
Name: "cus",
|
||||||
Count: 42,
|
Count: 42,
|
||||||
},
|
},
|
||||||
},
|
FieldSpec: types.FieldSpec{Path: "spec/template/replicas"},
|
||||||
fsslice: types.FsSlice{
|
|
||||||
{
|
|
||||||
Path: "spec/template/replicas",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Path: "spec/replicas",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
tc.filter.FsSlice = append(config.Replicas, tc.fsslice...)
|
|
||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(tc.expected),
|
strings.TrimSpace(tc.expected),
|
||||||
strings.TrimSpace(
|
strings.TrimSpace(
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/transform"
|
"sigs.k8s.io/kustomize/api/filters/replicacount"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/filtersutil"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/resid"
|
"sigs.k8s.io/kustomize/api/resid"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
@@ -34,21 +35,27 @@ func (p *plugin) Config(
|
|||||||
|
|
||||||
func (p *plugin) Transform(m resmap.ResMap) error {
|
func (p *plugin) Transform(m resmap.ResMap) error {
|
||||||
found := false
|
found := false
|
||||||
for i, replicaSpec := range p.FieldSpecs {
|
for _, fs := range p.FieldSpecs {
|
||||||
matcher := p.createMatcher(i)
|
matcher := p.createMatcher(fs)
|
||||||
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
||||||
matchCurrent := m.GetMatchingResourcesByCurrentId(matcher)
|
resList := append(
|
||||||
|
matchOriginal, m.GetMatchingResourcesByCurrentId(matcher)...)
|
||||||
for _, res := range append(matchOriginal, matchCurrent...) {
|
if len(resList) > 0 {
|
||||||
found = true
|
found = true
|
||||||
err := transform.MutateField(
|
for _, r := range resList {
|
||||||
res.Map(), replicaSpec.PathSlice(),
|
// There are redundant checks in the filter
|
||||||
replicaSpec.CreateIfNotPresent, p.addReplicas)
|
// that we'll live with until resolution of
|
||||||
|
// https://github.com/kubernetes-sigs/kustomize/issues/2506
|
||||||
|
err := filtersutil.ApplyToJSON(replicacount.Filter{
|
||||||
|
Replica: p.Replica,
|
||||||
|
FieldSpec: fs,
|
||||||
|
}, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
gvks := make([]string, len(p.FieldSpecs))
|
gvks := make([]string, len(p.FieldSpecs))
|
||||||
@@ -63,26 +70,8 @@ func (p *plugin) Transform(m resmap.ResMap) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Match Replica.Name and FieldSpec
|
// Match Replica.Name and FieldSpec
|
||||||
func (p *plugin) createMatcher(i int) resmap.IdMatcher {
|
func (p *plugin) createMatcher(fs types.FieldSpec) resmap.IdMatcher {
|
||||||
return func(r resid.ResId) bool {
|
return func(r resid.ResId) bool {
|
||||||
return r.Name == p.Replica.Name &&
|
return r.Name == p.Replica.Name && r.Gvk.IsSelected(&fs.Gvk)
|
||||||
r.Gvk.IsSelected(&p.FieldSpecs[i].Gvk)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *plugin) addReplicas(in interface{}) (interface{}, error) {
|
|
||||||
switch m := in.(type) {
|
|
||||||
case int64:
|
|
||||||
// Was already in the field.
|
|
||||||
case map[string]interface{}:
|
|
||||||
if len(m) != 0 {
|
|
||||||
// A map was already in the replicas field, don't want to
|
|
||||||
// discard this data silently.
|
|
||||||
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
|
|
||||||
}
|
|
||||||
// Just got added, default type is map, but we can return anything.
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("%#v is expected to be %T", in, m)
|
|
||||||
}
|
|
||||||
return p.Replica.Count, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ go 1.14
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
sigs.k8s.io/kustomize/api v0.5.1
|
sigs.k8s.io/kustomize/api v0.5.1
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.4.1
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user