From 96926fecce3052dc6a3095687a57c8036c1afb36 Mon Sep 17 00:00:00 2001 From: Phillip Wittrock Date: Mon, 30 Mar 2020 12:29:53 -0700 Subject: [PATCH] kyaml implementation of the PrefixSuffixTransformer --- api/filters/namespace/namespace.go | 2 +- api/filters/prefixsuffix/doc.go | 6 + api/filters/prefixsuffix/example_test.go | 47 +++++ api/filters/prefixsuffix/prefixsuffix.go | 43 +++++ api/filters/prefixsuffix/prefixsuffix_test.go | 167 ++++++++++++++++++ 5 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 api/filters/prefixsuffix/doc.go create mode 100644 api/filters/prefixsuffix/example_test.go create mode 100644 api/filters/prefixsuffix/prefixsuffix.go create mode 100644 api/filters/prefixsuffix/prefixsuffix_test.go diff --git a/api/filters/namespace/namespace.go b/api/filters/namespace/namespace.go index c8a610b22..677490c5f 100644 --- a/api/filters/namespace/namespace.go +++ b/api/filters/namespace/namespace.go @@ -15,7 +15,7 @@ type Filter struct { Namespace string `yaml:"namespace,omitempty"` // FsSlice contains the FieldSpecs to locate the namespace field - FsSlice types.FsSlice + FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` } var _ kio.Filter = Filter{} diff --git a/api/filters/prefixsuffix/doc.go b/api/filters/prefixsuffix/doc.go new file mode 100644 index 000000000..319374436 --- /dev/null +++ b/api/filters/prefixsuffix/doc.go @@ -0,0 +1,6 @@ +// Copyright 2020 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +// Package prefixsuffix contains a kio.Filter implementation of the kustomize +// PrefixSuffixTransformer. +package prefixsuffix diff --git a/api/filters/prefixsuffix/example_test.go b/api/filters/prefixsuffix/example_test.go new file mode 100644 index 000000000..67eeecfbf --- /dev/null +++ b/api/filters/prefixsuffix/example_test.go @@ -0,0 +1,47 @@ +// Copyright 2020 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package prefixsuffix_test + +import ( + "bytes" + "log" + "os" + + "sigs.k8s.io/kustomize/api/filters/prefixsuffix" + "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" + "sigs.k8s.io/kustomize/kyaml/kio" +) + +func ExampleFilter() { + fss := builtinconfig.MakeDefaultConfig().NamePrefix + err := kio.Pipeline{ + Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`)}}, + Filters: []kio.Filter{prefixsuffix.Filter{Prefix: "baz-", FsSlice: fss}}, + Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}}, + }.Execute() + if err != nil { + log.Fatal(err) + } + + // Output: + // apiVersion: example.com/v1 + // kind: Foo + // metadata: + // name: baz-instance + // --- + // apiVersion: example.com/v1 + // kind: Bar + // metadata: + // name: baz-instance +} diff --git a/api/filters/prefixsuffix/prefixsuffix.go b/api/filters/prefixsuffix/prefixsuffix.go new file mode 100644 index 000000000..f461831fd --- /dev/null +++ b/api/filters/prefixsuffix/prefixsuffix.go @@ -0,0 +1,43 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package prefixsuffix + +import ( + "fmt" + + "sigs.k8s.io/kustomize/api/filters/fsslice" + "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +// Filter applies resource name prefix's and suffix's using the fieldSpecs +type Filter struct { + Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` + Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` + + FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` +} + +var _ kio.Filter = Filter{} + +func (ns Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { + return kio.FilterAll(yaml.FilterFunc(ns.run)).Filter(nodes) +} + +// Run runs the filter on a single node rather than a slice +func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) { + // transformations based on data -- :) + err := node.PipeE(fsslice.Filter{ + FsSlice: ns.FsSlice, + SetValue: ns.set, + CreateKind: yaml.ScalarNode, // Name is a ScalarNode + }) + return node, err +} + +func (ns Filter) set(node *yaml.RNode) error { + return fsslice.SetScalar(fmt.Sprintf( + "%s%s%s", ns.Prefix, node.YNode().Value, ns.Suffix))(node) +} diff --git a/api/filters/prefixsuffix/prefixsuffix_test.go b/api/filters/prefixsuffix/prefixsuffix_test.go new file mode 100644 index 000000000..67beeefe9 --- /dev/null +++ b/api/filters/prefixsuffix/prefixsuffix_test.go @@ -0,0 +1,167 @@ +// Copyright 2019 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package prefixsuffix_test + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/filters/prefixsuffix" + "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" + filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" + "sigs.k8s.io/kustomize/api/types" +) + +var tests = []TestCase{ + { + name: "prefix", + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: foo-instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: foo-instance +`, + filter: prefixsuffix.Filter{Prefix: "foo-"}, + }, + + { + name: "suffix", + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance-foo +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance-foo +`, + filter: prefixsuffix.Filter{Suffix: "-foo"}, + }, + + { + name: "prefix-suffix", + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: bar-instance-foo +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: bar-instance-foo +`, + filter: prefixsuffix.Filter{Prefix: "bar-", Suffix: "-foo"}, + }, + + { + name: "data-fieldspecs", + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +a: + b: + c: d +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +a: + b: + c: d +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: foo-instance +a: + b: + c: foo-d +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: foo-instance +a: + b: + c: foo-d +`, + filter: prefixsuffix.Filter{Prefix: "foo-"}, + fsslice: []types.FieldSpec{ + { + Path: "a/b/c", + }, + }, + }, +} + +type TestCase struct { + name string + input string + expected string + filter prefixsuffix.Filter + fsslice types.FsSlice +} + +var config = builtinconfig.MakeDefaultConfig() + +func TestFilter(t *testing.T) { + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + test.filter.FsSlice = append(config.NamePrefix, test.fsslice...) + if !assert.Equal(t, + strings.TrimSpace(test.expected), + strings.TrimSpace( + filtertest_test.RunFilter(t, test.input, test.filter))) { + t.FailNow() + } + }) + } +}