Compare commits

..

11 Commits

Author SHA1 Message Date
Jeff Regan
27b2c7f294 Update formatting of component_test.go 2020-07-17 18:31:54 -07:00
Jeff Regan
03d6229c0b Merge pull request #2732 from monopole/beanPole
Switch prefix transformer to kyaml.
2020-07-17 18:09:19 -07:00
jregan
71b7b00bd8 Switch prefix transformer to kyaml. 2020-07-17 16:08:41 -07:00
Jeff Regan
e9396dca2c Merge pull request #2731 from prachirp/go-plugins
Fix go plugins caveats link
2020-07-17 15:49:36 -07:00
Prachi Pendse
bc581b70bf Fix go plugins caveats link 2020-07-17 12:03:19 -07:00
Jeff Regan
ac1c31c82b Merge pull request #2730 from monopole/addTest
Add a test and temporarily disable some plugin tests.
2020-07-17 10:25:07 -07:00
jregan
c878957d0b Add a test and temporarily disable some plugin tests. 2020-07-17 08:23:11 -07:00
Jeff Regan
0b359d0ef0 Merge pull request #2727 from monopole/addE2eTests
Pre v3.8.1; Add e2e tests pinned at v3.8.0
2020-07-15 17:54:54 -07:00
jregan
22ee7cbd49 Pre v3.8.1; Add e2e tests pinned at v3.8.0 2020-07-15 17:33:43 -07:00
Jeff Regan
7bf9c7002f Merge pull request #2726 from monopole/pinToKustomizeApiV_0_5_1
Pin to kustomize/api v0.5.1
2020-07-15 17:26:12 -07:00
jregan
155411f229 Pin to kustomize/api v0.5.1 2020-07-15 17:00:33 -07:00
56 changed files with 948 additions and 617 deletions

View File

@@ -14,8 +14,8 @@ all: verify-kustomize
verify-kustomize: \ verify-kustomize: \
lint-kustomize \ lint-kustomize \
test-unit-kustomize-all \ test-unit-kustomize-all \
test-examples-kustomize-against-HEAD test-examples-kustomize-against-HEAD \
# test-examples-kustomize-against-3.7.0 test-examples-kustomize-against-3.8.0
# The following target referenced by a file in # The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize # https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -23,10 +23,10 @@ verify-kustomize: \
prow-presubmit-check: \ prow-presubmit-check: \
lint-kustomize \ lint-kustomize \
test-unit-kustomize-all \ test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-unit-cmd-all \ test-unit-cmd-all \
test-go-mod test-go-mod \
# test-examples-kustomize-against-3.7.0 \ test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0
.PHONY: verify-kustomize-e2e .PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -233,10 +233,10 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD ./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY: .PHONY:
test-examples-kustomize-against-3.7.0: $(MYGOBIN)/mdrip test-examples-kustomize-against-3.8.0: $(MYGOBIN)/mdrip
( \ ( \
set -e; \ set -e; \
tag=v3.7.0; \ tag=v3.8.0; \
/bin/rm -f $(MYGOBIN)/kustomize; \ /bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \ echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \ GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \

View File

@@ -5,31 +5,27 @@ package builtins
import ( import (
"errors" "errors"
"fmt"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
// Add the given prefix and suffix to the field. // Add the given prefix and suffix to the field.
type PrefixSuffixTransformerPlugin struct { type PrefixSuffixTransformerPlugin struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` FieldSpecs types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
} }
// Not placed in a file yet due to lack of demand. // A Gvk skip list for prefix/suffix modification.
var prefixSuffixFieldSpecsToSkip = []types.FieldSpec{ // hard coded for now - eventually should be part of config.
{ var prefixSuffixFieldSpecsToSkip = types.FsSlice{
Gvk: resid.Gvk{Kind: "CustomResourceDefinition"}, {Gvk: resid.Gvk{Kind: "CustomResourceDefinition"}},
}, {Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"}},
{
Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"},
},
} }
func (p *PrefixSuffixTransformerPlugin) Config( func (p *PrefixSuffixTransformerPlugin) Config(
@@ -48,29 +44,24 @@ func (p *PrefixSuffixTransformerPlugin) Config(
} }
func (p *PrefixSuffixTransformerPlugin) Transform(m resmap.ResMap) error { func (p *PrefixSuffixTransformerPlugin) Transform(m resmap.ResMap) error {
// Even if both the Prefix and Suffix are empty we want // Even if both the Prefix and Suffix are empty we want
// to proceed with the transformation. This allows to add contextual // to proceed with the transformation. This allows to add contextual
// information to the resources (AddNamePrefix and AddNameSuffix). // information to the resources (AddNamePrefix and AddNameSuffix).
for _, r := range m.Resources() { for _, r := range m.Resources() {
// TODO: move this test into the filter (i.e. make a better filter)
if p.shouldSkip(r.OrgId()) { if p.shouldSkip(r.OrgId()) {
// Don't change the actual definition
// of a CRD.
continue continue
} }
id := r.OrgId() id := r.OrgId()
// current default configuration contains // current default configuration contains
// only one entry: "metadata/name" with no GVK // only one entry: "metadata/name" with no GVK
for _, path := range p.FieldSpecs { for _, fs := range p.FieldSpecs {
if !id.IsSelected(&path.Gvk) { // TODO: this is redundant to filter (but needed for now)
// With the currrent default configuration, if !id.IsSelected(&fs.Gvk) {
// because no Gvk is specified, so a wild
// card
continue continue
} }
// TODO: move this test into the filter.
if smellsLikeANameChange(&path) { if smellsLikeANameChange(&fs) {
// "metadata/name" is the only field. // "metadata/name" is the only field.
// this will add a prefix and a suffix // this will add a prefix and a suffix
// to the resource even if those are // to the resource even if those are
@@ -78,15 +69,11 @@ func (p *PrefixSuffixTransformerPlugin) Transform(m resmap.ResMap) error {
r.AddNamePrefix(p.Prefix) r.AddNamePrefix(p.Prefix)
r.AddNameSuffix(p.Suffix) r.AddNameSuffix(p.Suffix)
} }
err := filtersutil.ApplyToJSON(prefixsuffix.Filter{
// the addPrefixSuffix method will not Prefix: p.Prefix,
// change the name if both the prefix and suffix Suffix: p.Suffix,
// are empty. FieldSpec: fs,
err := transform.MutateField( }, r)
r.Map(),
path.PathSlice(),
path.CreateIfNotPresent,
p.addPrefixSuffix)
if err != nil { if err != nil {
return err return err
} }
@@ -99,8 +86,7 @@ func smellsLikeANameChange(fs *types.FieldSpec) bool {
return fs.Path == "metadata/name" return fs.Path == "metadata/name"
} }
func (p *PrefixSuffixTransformerPlugin) shouldSkip( func (p *PrefixSuffixTransformerPlugin) shouldSkip(id resid.ResId) bool {
id resid.ResId) bool {
for _, path := range prefixSuffixFieldSpecsToSkip { for _, path := range prefixSuffixFieldSpecsToSkip {
if id.IsSelected(&path.Gvk) { if id.IsSelected(&path.Gvk) {
return true return true
@@ -109,15 +95,6 @@ func (p *PrefixSuffixTransformerPlugin) shouldSkip(
return false return false
} }
func (p *PrefixSuffixTransformerPlugin) addPrefixSuffix(
in interface{}) (interface{}, error) {
s, ok := in.(string)
if !ok {
return nil, fmt.Errorf("%#v is expected to be %T", in, s)
}
return fmt.Sprintf("%s%s%s", p.Prefix, s, p.Suffix), nil
}
func NewPrefixSuffixTransformerPlugin() resmap.TransformerPlugin { func NewPrefixSuffixTransformerPlugin() resmap.TransformerPlugin {
return &PrefixSuffixTransformerPlugin{} return &PrefixSuffixTransformerPlugin{}
} }

View File

@@ -30,7 +30,7 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for _, k := range keys { for _, k := range keys {
if err := node.PipeE(fsslice.Filter{ if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice, FsSlice: f.FsSlice,
SetValue: fsslice.SetEntry(k, f.Annotations[k], yaml.StringTag), SetValue: filtersutil.SetEntry(k, f.Annotations[k], yaml.StringTag),
CreateKind: yaml.MappingNode, // Annotations are MappingNodes. CreateKind: yaml.MappingNode, // Annotations are MappingNodes.
CreateTag: "!!map", CreateTag: "!!map",
}); err != nil { }); err != nil {

View File

@@ -0,0 +1,6 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package fieldspec contains a yaml.Filter to modify a resource
// that matches the FieldSpec.
package fieldspec

View File

@@ -0,0 +1,61 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fieldspec_test
import (
"bytes"
"log"
"os"
. "sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func ExampleFilter() {
in := &kio.ByteReader{
Reader: bytes.NewBufferString(`
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
---
apiVersion: example.com/v1
kind: Bar
metadata:
name: instance
`),
}
fltr := Filter{
CreateKind: yaml.ScalarNode,
SetValue: filtersutil.SetScalar("green"),
FieldSpec: types.FieldSpec{Path: "a/b", CreateIfNotPresent: true},
}
err := kio.Pipeline{
Inputs: []kio.Reader{in},
Filters: []kio.Filter{kio.FilterAll(fltr)},
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
}.Execute()
if err != nil {
log.Fatal(err)
}
// Output:
// apiVersion: example.com/v1
// kind: Foo
// metadata:
// name: instance
// a:
// b: green
// ---
// apiVersion: example.com/v1
// kind: Bar
// metadata:
// name: instance
// a:
// b: green
}

View File

@@ -1,24 +1,27 @@
// Copyright 2019 The Kubernetes Authors. // Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package fsslice package fieldspec
import ( import (
"strings" "strings"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
// fieldSpecFilter applies a single fieldSpec to a single object var _ yaml.Filter = Filter{}
// fieldSpecFilter stores internal state and should not be reused
type fieldSpecFilter struct { // Filter applies a single fieldSpec to a single object
// Filter stores internal state and should not be reused
type Filter struct {
// FieldSpec contains the path to the value to set. // FieldSpec contains the path to the value to set.
FieldSpec types.FieldSpec `yaml:"fieldSpec"` FieldSpec types.FieldSpec `yaml:"fieldSpec"`
// Set the field using this function // Set the field using this function
SetValue SetFn SetValue filtersutil.SetFn
// CreateKind defines the type of node to create if the field is not found // CreateKind defines the type of node to create if the field is not found
CreateKind yaml.Kind CreateKind yaml.Kind
@@ -29,7 +32,7 @@ type fieldSpecFilter struct {
path []string path []string
} }
func (fltr fieldSpecFilter) Filter(obj *yaml.RNode) (*yaml.RNode, error) { func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
// check if the FieldSpec applies to the object // check if the FieldSpec applies to the object
if match, err := isMatchGVK(fltr.FieldSpec, obj); !match || err != nil { if match, err := isMatchGVK(fltr.FieldSpec, obj); !match || err != nil {
return obj, errors.Wrap(err) return obj, errors.Wrap(err)
@@ -43,7 +46,7 @@ func (fltr fieldSpecFilter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
return obj, nil return obj, nil
} }
func (fltr fieldSpecFilter) filter(obj *yaml.RNode) error { func (fltr Filter) filter(obj *yaml.RNode) error {
if len(fltr.path) == 0 { if len(fltr.path) == 0 {
// found the field -- set its value // found the field -- set its value
return fltr.SetValue(obj) return fltr.SetValue(obj)
@@ -60,7 +63,7 @@ func (fltr fieldSpecFilter) filter(obj *yaml.RNode) error {
} }
// field calls filter on the field matching the next path element // field calls filter on the field matching the next path element
func (fltr fieldSpecFilter) field(obj *yaml.RNode) error { func (fltr Filter) field(obj *yaml.RNode) error {
fieldName, isSeq := isSequenceField(fltr.path[0]) fieldName, isSeq := isSequenceField(fltr.path[0])
// lookup the field matching the next path element // lookup the field matching the next path element
@@ -104,9 +107,9 @@ func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
} }
// seq calls filter on all sequence elements // seq calls filter on all sequence elements
func (fltr fieldSpecFilter) seq(obj *yaml.RNode) error { func (fltr Filter) seq(obj *yaml.RNode) error {
if err := obj.VisitElements(func(node *yaml.RNode) error { if err := obj.VisitElements(func(node *yaml.RNode) error {
// recurse on each element -- re-allocating a fieldSpecFilter is // recurse on each element -- re-allocating a Filter is
// not strictly required, but is more consistent with field // not strictly required, but is more consistent with field
// and less likely to have side effects // and less likely to have side effects
// keep the entire path -- it does not contain parts for sequences // keep the entire path -- it does not contain parts for sequences

View File

@@ -0,0 +1,380 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fieldspec_test
import (
"bytes"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type TestCase struct {
name string
input string
expected string
filter fieldspec.Filter
fieldSpec string
error string
}
var tests = []TestCase{
{
name: "update",
fieldSpec: `
path: a/b
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-kind-not-match",
fieldSpec: `
path: a/b
group: foo
kind: Bar1
`,
input: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-group-not-match",
fieldSpec: `
path: a/b
group: foo1
kind: Bar
`,
input: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-version-not-match",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "bad-version",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "bad-meta",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
error: "missing Resource metadata",
},
{
name: "miss-match-type",
fieldSpec: `
path: a/b/c
kind: Bar
`,
input: `
kind: Bar
a:
b: a
`,
error: "obj kind: Bar\na:\n b: a\n at path a/b/c: unsupported yaml node",
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "add",
fieldSpec: `
path: a/b/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {b: {c: {d: e}}}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "update-in-sequence",
fieldSpec: `
path: a/b[]/c/d
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: a
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
// Don't create a sequence
{
name: "empty-sequence-no-create",
fieldSpec: `
path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
// Create a new field for an element in a sequence
{
name: "empty-sequence-create",
fieldSpec: `
path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {d: e}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "group v1",
fieldSpec: `
path: a/b
group: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "version v1",
fieldSpec: `
path: a/b
version: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
a:
b: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
}
func TestFilter_Filter(t *testing.T) {
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
err := yaml.Unmarshal([]byte(test.fieldSpec), &test.filter.FieldSpec)
if !assert.NoError(t, err) {
t.FailNow()
}
out := &bytes.Buffer{}
rw := &kio.ByteReadWriter{
Reader: bytes.NewBufferString(test.input),
Writer: out,
OmitReaderAnnotations: true,
}
// run the filter
err = kio.Pipeline{
Inputs: []kio.Reader{rw},
Filters: []kio.Filter{kio.FilterAll(test.filter)},
Outputs: []kio.Writer{rw},
}.Execute()
if test.error != "" {
if !assert.EqualError(t, err, test.error) {
t.FailNow()
}
// stop rest of test
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
// check results
if !assert.Equal(t,
strings.TrimSpace(test.expected),
strings.TrimSpace(out.String())) {
t.FailNow()
}
})
}
}

View File

@@ -1,6 +1,6 @@
// Copyright 2019 The Kubernetes Authors. // Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package fsslice package fieldspec
import ( import (
"strings" "strings"

View File

@@ -1,6 +1,6 @@
// Copyright 2019 The Kubernetes Authors. // Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package fsslice package fieldspec
import ( import (
"strings" "strings"

View File

@@ -0,0 +1,33 @@
package filtersutil
import (
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// SetFn is a function that accepts an RNode to possibly modify.
type SetFn func(*yaml.RNode) error
// SetScalar returns a SetFn to set a scalar value
func SetScalar(value string) SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{StringValue: value})
}
}
// SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
Tag: tag,
}
if tag == yaml.StringTag && yaml.IsYaml1_1NonString(n) {
n.Style = yaml.DoubleQuotedStyle
}
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{
Name: key,
Value: yaml.NewRNode(n),
})
}
}

View File

@@ -1,6 +1,6 @@
// Copyright 2020 The Kubernetes Authors. // Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package fsslice contains a yaml.Filter to modify a resource using an // Package fsslice contains a yaml.Filter to modify a resource if
// FsSlice to identify fields to be updated within the resource. // it matches one or more FieldSpec entries.
package fsslice package fsslice

View File

@@ -8,6 +8,7 @@ import (
"log" "log"
"os" "os"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice" "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"
@@ -30,7 +31,7 @@ metadata:
} }
fltr := fsslice.Filter{ fltr := fsslice.Filter{
CreateKind: yaml.ScalarNode, CreateKind: yaml.ScalarNode,
SetValue: fsslice.SetScalar("green"), SetValue: filtersutil.SetScalar("green"),
FsSlice: []types.FieldSpec{ FsSlice: []types.FieldSpec{
{Path: "a/b", CreateIfNotPresent: true}, {Path: "a/b", CreateIfNotPresent: true},
}, },

View File

@@ -4,48 +4,22 @@
package fsslice package fsslice
import ( import (
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
// SetFn sets a value
type SetFn func(*yaml.RNode) error
// SetScalar returns a SetFn to set a scalar value
func SetScalar(value string) SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{StringValue: value})
}
}
// SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
Tag: tag,
}
if tag == yaml.StringTag && yaml.IsYaml1_1NonString(n) {
n.Style = yaml.DoubleQuotedStyle
}
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{
Name: key,
Value: yaml.NewRNode(n),
})
}
}
var _ yaml.Filter = Filter{} var _ yaml.Filter = Filter{}
// Filter uses an FsSlice to modify fields on a single object // Filter ranges over an FsSlice to modify fields on a single object.
// An FsSlice is a range of FieldSpecs. A FieldSpec is a GVK plus a path.
type Filter struct { type Filter struct {
// FieldSpecList list of FieldSpecs to set // FieldSpecList list of FieldSpecs to set
FsSlice types.FsSlice `yaml:"fsSlice"` FsSlice types.FsSlice `yaml:"fsSlice"`
// SetValue is called on each field that matches one of the FieldSpecs // SetValue is called on each field that matches one of the FieldSpecs
SetValue SetFn SetValue filtersutil.SetFn
// CreateKind is used to create fields that do not exist // CreateKind is used to create fields that do not exist
CreateKind yaml.Kind CreateKind yaml.Kind
@@ -59,7 +33,7 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
// apply this FieldSpec // apply this FieldSpec
// create a new filter for each iteration because they // create a new filter for each iteration because they
// store internal state about the field paths // store internal state about the field paths
_, err := (&fieldSpecFilter{ _, err := (&fieldspec.Filter{
FieldSpec: fltr.FsSlice[i], FieldSpec: fltr.FsSlice[i],
SetValue: fltr.SetValue, SetValue: fltr.SetValue,
CreateKind: fltr.CreateKind, CreateKind: fltr.CreateKind,

View File

@@ -9,335 +9,77 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/fsslice" "sigs.k8s.io/kustomize/api/filters/filtersutil"
. "sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
type TestCase struct { type TestCase struct {
name string
input string input string
expected string expected string
filter fsslice.Filter filter Filter
fsSlice string fsSlice string
error string error string
} }
var tests = []TestCase{ var tests = map[string]TestCase{
{ "empty": {
name: "update",
fsSlice: ` fsSlice: `
- path: a/b
group: foo
kind: Bar
`, `,
input: ` input: `
apiVersion: foo/v1beta1 apiVersion: foo/v1
kind: Bar kind: Bar
a:
b: c
`, `,
expected: ` expected: `
apiVersion: foo/v1beta1 apiVersion: foo/v1
kind: Bar kind: Bar
a:
b: e
`, `,
filter: fsslice.Filter{ filter: Filter{
SetValue: fsslice.SetScalar("e"), SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-kind-not-match",
fsSlice: `
- path: a/b
group: foo
kind: Bar1
`,
input: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "update-group-not-match",
fsSlice: `
- path: a/b
group: foo1
kind: Bar
`,
input: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "update-version-not-match",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "bad-version",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "bad-meta",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
error: "missing Resource metadata",
},
{
name: "miss-match-type",
fsSlice: `
- path: a/b/c
kind: Bar
`,
input: `
kind: Bar
a:
b: a
`,
error: "obj kind: Bar\na:\n b: a\n at path a/b/c: unsupported yaml node",
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "add",
fsSlice: `
- path: a/b/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {b: {c: {d: e}}}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode, CreateKind: yaml.ScalarNode,
}, },
}, },
"two": {
{
name: "update-in-sequence",
fsSlice: `
- path: a/b[]/c/d
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: a
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: e
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
// Don't create a sequence
{
name: "empty-sequence-no-create",
fsSlice: `
- path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
// Create a new field for an element in a sequence
{
name: "empty-sequence-create",
fsSlice: `
- path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {d: e}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "group v1",
fsSlice: ` fsSlice: `
- path: a/b - path: a/b
group: v1 group: foo
version: v1
create: true create: true
kind: Bar kind: Bar
`, - path: q/r[]/s/t
input: ` group: foo
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "version v1",
fsSlice: `
- path: a/b
version: v1 version: v1
create: true create: true
kind: Bar kind: Bar
`, `,
input: ` input: `
apiVersion: v1 apiVersion: foo/v1
kind: Bar kind: Bar
q:
r:
- s: {}
`, `,
expected: ` expected: `
apiVersion: v1 apiVersion: foo/v1
kind: Bar kind: Bar
q:
r:
- s: {t: e}
a: a:
b: e b: e
`, `,
filter: fsslice.Filter{ filter: Filter{
SetValue: fsslice.SetScalar("e"), SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode, CreateKind: yaml.ScalarNode,
}, },
}, },
} }
func TestFilter_Filter(t *testing.T) { func TestFilter(t *testing.T) {
for i := range tests { for name := range tests {
test := tests[i] test := tests[name]
t.Run(test.name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
err := yaml.Unmarshal([]byte(test.fsSlice), &test.filter.FsSlice) err := yaml.Unmarshal([]byte(test.fsSlice), &test.filter.FsSlice)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()

View File

@@ -4,6 +4,7 @@
package imagetag package imagetag
import ( import (
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice" "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"
@@ -35,7 +36,7 @@ func (f Filter) filter(node *yaml.RNode) (*yaml.RNode, error) {
return node, nil return node, nil
} }
func updateImageTagFn(imageTag types.Image) fsslice.SetFn { func updateImageTagFn(imageTag types.Image) filtersutil.SetFn {
return func(node *yaml.RNode) error { return func(node *yaml.RNode) error {
return node.PipeE(imageTagUpdater{ return node.PipeE(imageTagUpdater{
ImageTag: imageTag, ImageTag: imageTag,

View File

@@ -31,7 +31,7 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for _, k := range keys { for _, k := range keys {
if err := node.PipeE(fsslice.Filter{ if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice, FsSlice: f.FsSlice,
SetValue: fsslice.SetEntry(k, f.Labels[k], yaml.StringTag), SetValue: filtersutil.SetEntry(k, f.Labels[k], yaml.StringTag),
CreateKind: yaml.MappingNode, // Labels are MappingNodes. CreateKind: yaml.MappingNode, // Labels are MappingNodes.
CreateTag: "!!map", CreateTag: "!!map",
}); err != nil { }); err != nil {

View File

@@ -4,6 +4,8 @@
package namespace package namespace
import ( import (
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice" "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"
@@ -42,7 +44,7 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
// transformations based on data -- :) // transformations based on data -- :)
err := node.PipeE(fsslice.Filter{ err := node.PipeE(fsslice.Filter{
FsSlice: ns.FsSlice, FsSlice: ns.FsSlice,
SetValue: fsslice.SetScalar(ns.Namespace), SetValue: filtersutil.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
CreateTag: yaml.StringTag, CreateTag: yaml.StringTag,
}) })
@@ -73,7 +75,7 @@ func (ns Filter) hacks(obj *yaml.RNode) error {
// if they are cluster scoped through either an annotation on the resources, // if they are cluster scoped through either an annotation on the resources,
// or through inlined OpenAPI on the resource as a YAML comment. // or through inlined OpenAPI on the resource as a YAML comment.
func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) error { func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) error {
gvk := fsslice.GetGVK(meta) gvk := fieldspec.GetGVK(meta)
if !gvk.IsNamespaceableKind() { if !gvk.IsNamespaceableKind() {
return nil return nil
} }
@@ -81,7 +83,7 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) erro
FsSlice: []types.FieldSpec{ FsSlice: []types.FieldSpec{
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true}, {Path: types.MetadataNamespacePath, CreateIfNotPresent: true},
}, },
SetValue: fsslice.SetScalar(ns.Namespace), SetValue: filtersutil.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
} }
_, err := f.Filter(obj) _, err := f.Filter(obj)

View File

@@ -9,12 +9,11 @@ import (
"os" "os"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix" "sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
) )
func ExampleFilter() { func ExampleFilter() {
fss := builtinconfig.MakeDefaultConfig().NamePrefix
err := kio.Pipeline{ err := kio.Pipeline{
Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(` Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(`
apiVersion: example.com/v1 apiVersion: example.com/v1
@@ -27,7 +26,8 @@ kind: Bar
metadata: metadata:
name: instance name: instance
`)}}, `)}},
Filters: []kio.Filter{prefixsuffix.Filter{Prefix: "baz-", FsSlice: fss}}, Filters: []kio.Filter{prefixsuffix.Filter{
Prefix: "baz-", FieldSpec: types.FieldSpec{Path: "metadata/name"}}},
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}}, Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
}.Execute() }.Execute()
if err != nil { if err != nil {

View File

@@ -6,7 +6,8 @@ package prefixsuffix
import ( import (
"fmt" "fmt"
"sigs.k8s.io/kustomize/api/filters/fsslice" "sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"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"
@@ -17,28 +18,26 @@ type Filter struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"`
} }
var _ kio.Filter = Filter{} var _ kio.Filter = Filter{}
func (ns Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
return kio.FilterAll(yaml.FilterFunc(ns.run)).Filter(nodes) return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
} }
// Run runs the filter on a single node rather than a slice func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) { err := node.PipeE(fieldspec.Filter{
// transformations based on data -- :) FieldSpec: f.FieldSpec,
err := node.PipeE(fsslice.Filter{ SetValue: f.evaluateField,
FsSlice: ns.FsSlice,
SetValue: ns.set,
CreateKind: yaml.ScalarNode, // Name is a ScalarNode CreateKind: yaml.ScalarNode, // Name is a ScalarNode
CreateTag: yaml.StringTag, CreateTag: yaml.StringTag,
}) })
return node, err return node, err
} }
func (ns Filter) set(node *yaml.RNode) error { func (f Filter) evaluateField(node *yaml.RNode) error {
return fsslice.SetScalar(fmt.Sprintf( return filtersutil.SetScalar(fmt.Sprintf(
"%s%s%s", ns.Prefix, node.YNode().Value, ns.Suffix))(node) "%s%s%s", f.Prefix, node.YNode().Value, f.Suffix))(node)
} }

View File

@@ -9,14 +9,12 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix" "sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"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"
) )
var tests = []TestCase{ var tests = map[string]TestCase{
{ "prefix": {
name: "prefix",
input: ` input: `
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Foo kind: Foo
@@ -40,10 +38,10 @@ metadata:
name: foo-instance name: foo-instance
`, `,
filter: prefixsuffix.Filter{Prefix: "foo-"}, filter: prefixsuffix.Filter{Prefix: "foo-"},
fs: types.FieldSpec{Path: "metadata/name"},
}, },
{ "suffix": {
name: "suffix",
input: ` input: `
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Foo kind: Foo
@@ -67,10 +65,10 @@ metadata:
name: instance-foo name: instance-foo
`, `,
filter: prefixsuffix.Filter{Suffix: "-foo"}, filter: prefixsuffix.Filter{Suffix: "-foo"},
fs: types.FieldSpec{Path: "metadata/name"},
}, },
{ "prefix-suffix": {
name: "prefix-suffix",
input: ` input: `
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Foo kind: Foo
@@ -94,10 +92,10 @@ metadata:
name: bar-instance-foo name: bar-instance-foo
`, `,
filter: prefixsuffix.Filter{Prefix: "bar-", Suffix: "-foo"}, filter: prefixsuffix.Filter{Prefix: "bar-", Suffix: "-foo"},
fs: types.FieldSpec{Path: "metadata/name"},
}, },
{ "data-fieldspecs": {
name: "data-fieldspecs",
input: ` input: `
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Foo kind: Foo
@@ -119,7 +117,7 @@ a:
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Foo kind: Foo
metadata: metadata:
name: foo-instance name: instance
a: a:
b: b:
c: foo-d c: foo-d
@@ -127,35 +125,28 @@ a:
apiVersion: example.com/v1 apiVersion: example.com/v1
kind: Bar kind: Bar
metadata: metadata:
name: foo-instance name: instance
a: a:
b: b:
c: foo-d c: foo-d
`, `,
filter: prefixsuffix.Filter{Prefix: "foo-"}, filter: prefixsuffix.Filter{Prefix: "foo-"},
fsslice: []types.FieldSpec{ fs: types.FieldSpec{Path: "a/b/c"},
{
Path: "a/b/c",
},
},
}, },
} }
type TestCase struct { type TestCase struct {
name string
input string input string
expected string expected string
filter prefixsuffix.Filter filter prefixsuffix.Filter
fsslice types.FsSlice fs types.FieldSpec
} }
var config = builtinconfig.MakeDefaultConfig()
func TestFilter(t *testing.T) { func TestFilter(t *testing.T) {
for i := range tests { for name := range tests {
test := tests[i] test := tests[name]
t.Run(test.name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
test.filter.FsSlice = append(config.NamePrefix, test.fsslice...) test.filter.FieldSpec = test.fs
if !assert.Equal(t, if !assert.Equal(t,
strings.TrimSpace(test.expected), strings.TrimSpace(test.expected),
strings.TrimSpace( strings.TrimSpace(

View File

@@ -3,6 +3,7 @@ package replicacount
import ( import (
"strconv" "strconv"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice" "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"
@@ -45,5 +46,5 @@ func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
} }
func (rc Filter) set(node *yaml.RNode) error { func (rc Filter) set(node *yaml.RNode) error {
return fsslice.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node) return filtersutil.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node)
} }

View File

@@ -19,3 +19,5 @@ require (
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/kyaml v0.4.1 => ../kyaml

View File

@@ -580,8 +580,6 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.4.1 h1:NEqA/35upoAjb+I5vh1ODUqxoX4DOrezeQa9BhhG5Co=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -104,7 +104,7 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) {
} }
// MakeCustomizedResMap creates a fully customized ResMap // MakeCustomizedResMap creates a fully customized ResMap
// per the instructions contained in its kustomiztion instance. // per the instructions contained in its kustomization instance.
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
return kt.makeCustomizedResMap() return kt.makeCustomizedResMap()
} }

View File

@@ -39,8 +39,8 @@ resources:
configMapGenerator: configMapGenerator:
- name: my-configmap - name: my-configmap
literals: literals:
- testValue=1 - testValue=1
- otherValue=10 - otherValue=10
`) `)
th.WriteF("/app/base/deploy.yaml", ` th.WriteF("/app/base/deploy.yaml", `
apiVersion: v1 apiVersion: v1
@@ -59,13 +59,13 @@ replicas:
- name: storefront - name: storefront
count: 3 count: 3
resources: resources:
- stub.yaml - stub.yaml
configMapGenerator: configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- testValue=2 - testValue=2
- compValue=5 - compValue=5
`) `)
th.WriteF("/app/comp/stub.yaml", ` th.WriteF("/app/comp/stub.yaml", `
apiVersion: v1 apiVersion: v1
@@ -156,7 +156,7 @@ configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- otherValue=9 - otherValue=9
`), `),
writeK("/app/prod", ` writeK("/app/prod", `
resources: resources:
@@ -212,7 +212,7 @@ configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- otherValue=9 - otherValue=9
`), `),
writeK("/app/prod", ` writeK("/app/prod", `
resources: resources:
@@ -327,8 +327,8 @@ configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- compValue=5 - compValue=5
- testValue=2 - testValue=2
`), `),
}, },
runPath: "/app/direct-component", runPath: "/app/direct-component",
@@ -360,7 +360,7 @@ configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- otherValue=9 - otherValue=9
`), `),
}, },
runPath: "/app/prod", runPath: "/app/prod",
@@ -574,7 +574,7 @@ configMapGenerator:
- name: my-configmap - name: my-configmap
behavior: merge behavior: merge
literals: literals:
- otherValue=9 - otherValue=9
`), `),
}, },
runPath: "/app/prod", runPath: "/app/prod",

View File

@@ -10,24 +10,6 @@ import (
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
) )
func writeDeployment(th *kusttest_test.HarnessEnhanced, path string) {
th.WriteF(path, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- name: whatever
image: whatever
`)
}
func writeStringPrefixer(th *kusttest_test.HarnessEnhanced, path, name string) { func writeStringPrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, ` th.WriteF(path, `
apiVersion: someteam.example.com/v1 apiVersion: someteam.example.com/v1
@@ -37,53 +19,6 @@ metadata:
`) `)
} }
func writeDatePrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, `
apiVersion: someteam.example.com/v1
kind: DatePrefixer
metadata:
name: `+name+`
`)
}
func TestOrderedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
BuildGoPlugin("someteam.example.com", "v1", "DatePrefixer")
defer th.Reset()
th.WriteK("/app", `
resources:
- deployment.yaml
transformers:
- peachPrefixer.yaml
- date1Prefixer.yaml
- applePrefixer.yaml
- date2Prefixer.yaml
`)
writeDeployment(th, "/app/deployment.yaml")
writeStringPrefixer(th, "/app/applePrefixer.yaml", "apple")
writeStringPrefixer(th, "/app/peachPrefixer.yaml", "peach")
writeDatePrefixer(th, "/app/date1Prefixer.yaml", "date1")
writeDatePrefixer(th, "/app/date2Prefixer.yaml", "date2")
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: 2018-05-11-apple-2018-05-11-peach-myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- image: whatever
name: whatever
`)
}
func TestPluginsNotEnabled(t *testing.T) { func TestPluginsNotEnabled(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t). th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer") BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer")
@@ -165,6 +100,78 @@ metadata:
`) `)
} }
/*
The tests below are disabled until the StringPrefixer and DatePrefixer
can be rewritten using kyaml, instead of depending on the
PrefixSuffixTransformerPlugin. That dependency is causing
failures in the test loader.
func writeDeployment(th *kusttest_test.HarnessEnhanced, path string) {
th.WriteF(path, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- name: whatever
image: whatever
`)
}
func writeDatePrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, `
apiVersion: someteam.example.com/v1
kind: DatePrefixer
metadata:
name: `+name+`
`)
}
func TestOrderedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
BuildGoPlugin("someteam.example.com", "v1", "DatePrefixer")
defer th.Reset()
th.WriteK("/app", `
resources:
- deployment.yaml
transformers:
- peachPrefixer.yaml
- date1Prefixer.yaml
- applePrefixer.yaml
- date2Prefixer.yaml
`)
writeDeployment(th, "/app/deployment.yaml")
writeStringPrefixer(th, "/app/applePrefixer.yaml", "apple")
writeStringPrefixer(th, "/app/peachPrefixer.yaml", "peach")
writeDatePrefixer(th, "/app/date1Prefixer.yaml", "date1")
writeDatePrefixer(th, "/app/date2Prefixer.yaml", "date2")
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: 2018-05-11-apple-2018-05-11-peach-myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- image: whatever
name: whatever
`)
}
func TestTransformedTransformers(t *testing.T) { func TestTransformedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t). th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer"). BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
@@ -205,3 +212,4 @@ spec:
name: whatever name: whatever
`) `)
} }
*/

View File

@@ -13,6 +13,178 @@ import (
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
) )
func TestSliceFromBytes(t *testing.T) {
type testCase struct {
input string
expected []string
}
testCases := map[string]testCase{
"empty1": {
input: "",
expected: []string{},
},
"empty2": {
input: `
---
---
`,
expected: []string{},
},
"deployment1": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: pooh
---
`,
expected: []string{
`apiVersion: apps/v1
kind: Deployment
metadata:
name: pooh
`,
},
},
"deployment2": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot
spec:
replicas: 1
selector:
matchLabels:
foo: bar
template:
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
spec:
containers:
- env:
- name: foo
value: bar
image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot-service
spec:
ports:
- port: 7002
selector:
app: mungebot
foo: bar
`,
expected: []string{
`apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot
spec:
replicas: 1
selector:
matchLabels:
foo: bar
template:
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
spec:
containers:
- env:
- name: foo
value: bar
image: nginx
name: nginx
ports:
- containerPort: 80
`,
`apiVersion: v1
kind: Service
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot-service
spec:
ports:
- port: 7002
selector:
app: mungebot
foo: bar
`,
},
},
}
for name := range testCases {
tc := testCases[name]
t.Run(name, func(t *testing.T) {
result, err := factory.SliceFromBytes([]byte(tc.input))
if err != nil {
t.Fatalf("%v: fails with err: %v", name, err)
}
if len(result) != len(tc.expected) {
for i := range result {
bytes, err := result[i].AsYAML()
if err != nil {
t.Fatalf("%v: result to YAML fails with err: %v", name, err)
}
tmp := string(bytes)
t.Logf("--- %d:\n%s", i, tmp)
}
t.Fatalf(
"%v: actual len %d != expected len %d",
name, len(result), len(tc.expected))
}
for i := range tc.expected {
bytes, err := result[i].AsYAML()
if err != nil {
t.Fatalf("%v: result to YAML fails with err: %v", name, err)
}
tmp := string(bytes)
if tmp != tc.expected[i] {
t.Fatalf(
"%v: string mismatch in item %d\n"+
"actual:\n-----\n%s\n-----\n"+
"expected:\n-----\n%s\n-----\n",
name, i, tmp, tc.expected[i])
}
}
})
}
}
func TestSliceFromPatches(t *testing.T) { func TestSliceFromPatches(t *testing.T) {
patchGood1 := types.PatchStrategicMerge("patch1.yaml") patchGood1 := types.PatchStrategicMerge("patch1.yaml")
patch1 := ` patch1 := `

View File

@@ -7,17 +7,14 @@ require (
github.com/spf13/cobra v1.0.0 github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
k8s.io/client-go v0.17.3 k8s.io/client-go v0.17.3
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/cmd/config v0.2.0 sigs.k8s.io/kustomize/cmd/config v0.2.0
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.1 => ../api
exclude ( exclude (
github.com/russross/blackfriday v2.0.0+incompatible github.com/russross/blackfriday v2.0.0+incompatible
sigs.k8s.io/kustomize/api v0.2.0 sigs.k8s.io/kustomize/api v0.2.0
) )
replace (
sigs.k8s.io/kustomize/api => ../api
sigs.k8s.io/kustomize/kyaml => ../kyaml
)

View File

@@ -670,6 +670,7 @@ gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
@@ -751,6 +752,10 @@ sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbL
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/kustomize/cmd/config v0.2.0 h1:VNAWKb1JLl7dFjMAD5MwdZpGjreN3qL63C8DKtsUYck= sigs.k8s.io/kustomize/cmd/config v0.2.0 h1:VNAWKb1JLl7dFjMAD5MwdZpGjreN3qL63C8DKtsUYck=
sigs.k8s.io/kustomize/cmd/config v0.2.0/go.mod h1:oXzY7QJS6JlmWgusEjra2O3cW7GSIICXa59/3DvjBfE= sigs.k8s.io/kustomize/cmd/config v0.2.0/go.mod h1:oXzY7QJS6JlmWgusEjra2O3cW7GSIICXa59/3DvjBfE=
sigs.k8s.io/kustomize/kyaml v0.1.4/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/kustomize/kyaml v0.2.0/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU=
sigs.k8s.io/kustomize/kyaml v0.4.1 h1:NEqA/35upoAjb+I5vh1ODUqxoX4DOrezeQa9BhhG5Co=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=

View File

@@ -3,9 +3,9 @@ module sigs.k8s.io/kustomize/plugin/builtin/annotationstransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/builtin/configmapgenerator
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/builtin/hashtransformer
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/builtin/imagetagtransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,9 +3,9 @@ module sigs.k8s.io/kustomize/plugin/builtin/labeltransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -4,7 +4,7 @@ go 1.14
require ( require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,9 +3,9 @@ module sigs.k8s.io/kustomize/plugin/builtin/namespacetransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -5,9 +5,9 @@ go 1.14
require ( require (
github.com/evanphx/json-patch v4.5.0+incompatible github.com/evanphx/json-patch v4.5.0+incompatible
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -4,9 +4,9 @@ go 1.14
require ( require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -4,9 +4,9 @@ go 1.14
require ( require (
github.com/evanphx/json-patch v4.5.0+incompatible github.com/evanphx/json-patch v4.5.0+incompatible
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -6,34 +6,30 @@ package main
import ( import (
"errors" "errors"
"fmt"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
// Add the given prefix and suffix to the field. // Add the given prefix and suffix to the field.
type plugin struct { type plugin struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` FieldSpecs types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
} }
//noinspection GoUnusedGlobalVariable //noinspection GoUnusedGlobalVariable
var KustomizePlugin plugin var KustomizePlugin plugin
// Not placed in a file yet due to lack of demand. // A Gvk skip list for prefix/suffix modification.
var prefixSuffixFieldSpecsToSkip = []types.FieldSpec{ // hard coded for now - eventually should be part of config.
{ var prefixSuffixFieldSpecsToSkip = types.FsSlice{
Gvk: resid.Gvk{Kind: "CustomResourceDefinition"}, {Gvk: resid.Gvk{Kind: "CustomResourceDefinition"}},
}, {Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"}},
{
Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"},
},
} }
func (p *plugin) Config( func (p *plugin) Config(
@@ -52,29 +48,24 @@ func (p *plugin) Config(
} }
func (p *plugin) Transform(m resmap.ResMap) error { func (p *plugin) Transform(m resmap.ResMap) error {
// Even if both the Prefix and Suffix are empty we want // Even if both the Prefix and Suffix are empty we want
// to proceed with the transformation. This allows to add contextual // to proceed with the transformation. This allows to add contextual
// information to the resources (AddNamePrefix and AddNameSuffix). // information to the resources (AddNamePrefix and AddNameSuffix).
for _, r := range m.Resources() { for _, r := range m.Resources() {
// TODO: move this test into the filter (i.e. make a better filter)
if p.shouldSkip(r.OrgId()) { if p.shouldSkip(r.OrgId()) {
// Don't change the actual definition
// of a CRD.
continue continue
} }
id := r.OrgId() id := r.OrgId()
// current default configuration contains // current default configuration contains
// only one entry: "metadata/name" with no GVK // only one entry: "metadata/name" with no GVK
for _, path := range p.FieldSpecs { for _, fs := range p.FieldSpecs {
if !id.IsSelected(&path.Gvk) { // TODO: this is redundant to filter (but needed for now)
// With the currrent default configuration, if !id.IsSelected(&fs.Gvk) {
// because no Gvk is specified, so a wild
// card
continue continue
} }
// TODO: move this test into the filter.
if smellsLikeANameChange(&path) { if smellsLikeANameChange(&fs) {
// "metadata/name" is the only field. // "metadata/name" is the only field.
// this will add a prefix and a suffix // this will add a prefix and a suffix
// to the resource even if those are // to the resource even if those are
@@ -82,15 +73,11 @@ func (p *plugin) Transform(m resmap.ResMap) error {
r.AddNamePrefix(p.Prefix) r.AddNamePrefix(p.Prefix)
r.AddNameSuffix(p.Suffix) r.AddNameSuffix(p.Suffix)
} }
err := filtersutil.ApplyToJSON(prefixsuffix.Filter{
// the addPrefixSuffix method will not Prefix: p.Prefix,
// change the name if both the prefix and suffix Suffix: p.Suffix,
// are empty. FieldSpec: fs,
err := transform.MutateField( }, r)
r.Map(),
path.PathSlice(),
path.CreateIfNotPresent,
p.addPrefixSuffix)
if err != nil { if err != nil {
return err return err
} }
@@ -103,8 +90,7 @@ func smellsLikeANameChange(fs *types.FieldSpec) bool {
return fs.Path == "metadata/name" return fs.Path == "metadata/name"
} }
func (p *plugin) shouldSkip( func (p *plugin) shouldSkip(id resid.ResId) bool {
id resid.ResId) bool {
for _, path := range prefixSuffixFieldSpecsToSkip { for _, path := range prefixSuffixFieldSpecsToSkip {
if id.IsSelected(&path.Gvk) { if id.IsSelected(&path.Gvk) {
return true return true
@@ -112,12 +98,3 @@ func (p *plugin) shouldSkip(
} }
return false return false
} }
func (p *plugin) addPrefixSuffix(
in interface{}) (interface{}, error) {
s, ok := in.(string)
if !ok {
return nil, fmt.Errorf("%#v is expected to be %T", in, s)
}
return fmt.Sprintf("%s%s%s", p.Prefix, s, p.Suffix), nil
}

View File

@@ -3,8 +3,9 @@ module sigs.k8s.io/kustomize/plugin/builtin/prefixsuffixtransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 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
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/builtin/replicacounttransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/builtin/secretgenerator
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -3,9 +3,9 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/valueaddtransformer
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/bashedconfigmap
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/chartinflator
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -4,8 +4,8 @@ go 1.14
require ( require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/gogetter
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/printworkdir
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/replacementtransform
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/secretsfromdatabase
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/sedtransformer
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -3,8 +3,8 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/someservicegenerator
go 1.14 go 1.14
require ( require (
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -4,8 +4,8 @@ go 1.14
require ( require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
sigs.k8s.io/kustomize/api v0.5.0 sigs.k8s.io/kustomize/api v0.5.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.2.0
) )
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -2,6 +2,6 @@ module sigs.k8s.io/kustomize/plugin/someteam.example.com/v1/validator
go 1.14 go 1.14
require sigs.k8s.io/kustomize/api v0.5.0 require sigs.k8s.io/kustomize/api v0.5.1
replace sigs.k8s.io/kustomize/api v0.5.0 => ../../../../api replace sigs.k8s.io/kustomize/api v0.5.1 => ../../../../api

View File

@@ -287,7 +287,7 @@ data:
### Go plugins ### Go plugins
Be sure to read [Go plugin caveats](goPluginCaveats.md). Be sure to read [Go plugin caveats](goplugincaveats/).
[Go plugin]: https://golang.org/pkg/plugin/ [Go plugin]: https://golang.org/pkg/plugin/