Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 9 additions & 45 deletions functions/go/apply-setters/applysetters/apply_setters.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,14 @@ import (
"strings"

"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

const SetterCommentIdentifier = "# kpt-set: "

var _ kio.Filter = &ApplySetters{}

// ApplySetters applies the setter values to the resource fields which are tagged
// by the setter reference comments
type ApplySetters struct {
// Setters holds the user provided values for all the setters
Setters []Setter

// Results are the results of applying setter values
Results []*Result

// filePath file path of resource
filePath string
}

type Setter struct {
// Name is the name of the setter
Name string

// Value is the input value for setter
Value string
}

// Result holds result of search and replace operation
type Result struct {
// FilePath is the file path of the matching field
FilePath string

// FieldPath is field path of the matching field
FieldPath string

// Value of the matching field
Value string
}

// Filter implements Set as a yaml.Filter
func (as *ApplySetters) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
func (as *Setters) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for i := range nodes {
filePath, _, err := kioutil.GetFileAnnotations(nodes[i])
if err != nil {
Expand Down Expand Up @@ -77,14 +41,13 @@ environments: # kpt-set: ${env}
- dev
- stage

For input ApplySetters [name: env, value: "[stage, prod]"], qthe yaml node is transformed to
For input Setters [name: env, value: "[stage, prod]"], qthe yaml node is transformed to

environments: # kpt-set: ${env}
- stage
- prod

*/
func (as *ApplySetters) visitMapping(object *yaml.RNode, path string) error {
func (as *Setters) visitMapping(object *yaml.RNode, path string) error {
return object.VisitFields(func(node *yaml.MapNode) error {
if node == nil || node.Key.IsNil() || node.Value.IsNil() {
// don't do IsNilOrEmpty check as empty sequences are allowed
Expand Down Expand Up @@ -180,17 +143,18 @@ e.g.for input of scalar node 'nginx:1.7.1 # kpt-set: ${image}:${tag}' in the yam

apiVersion: v1
...
image: nginx:1.7.1 # kpt-set: ${image}:${tag}

and for input ApplySetters [[name: image, value: ubuntu], [name: tag, value: 1.8.0]]
image: nginx:1.7.1 # kpt-set: ${image}:${tag}

and for input Setters [[name: image, value: ubuntu], [name: tag, value: 1.8.0]]
The yaml node is transformed to

apiVersion: v1
...
image: ubuntu:1.8.0 # kpt-set: ${image}:${tag}

image: ubuntu:1.8.0 # kpt-set: ${image}:${tag}
*/
func (as *ApplySetters) visitScalar(object *yaml.RNode, path string) error {
func (as *Setters) visitScalar(object *yaml.RNode, path string) error {
if object.IsNil() {
return nil
}
Expand Down Expand Up @@ -358,7 +322,7 @@ func clean(input string) string {
}

// Decode decodes the input yaml node into Set struct
func Decode(rn *yaml.RNode, fcd *ApplySetters) {
func Decode(rn *yaml.RNode, fcd *Setters) {
for k, v := range rn.GetDataMap() {
fcd.Setters = append(fcd.Setters, Setter{Name: k, Value: v})
}
Expand Down
66 changes: 33 additions & 33 deletions functions/go/apply-setters/applysetters/apply_setters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
Expand All @@ -108,8 +108,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: ubuntu:1.8.0 # kpt-set: ${image}:${tag}
- name: nginx
image: ubuntu:1.8.0 # kpt-set: ${image}:${tag}
`,
},
{
Expand All @@ -127,8 +127,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}`,
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
metadata:
Expand All @@ -138,8 +138,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: ubuntu:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: ubuntu:1.7.9 # kpt-set: ${image}:${tag}
`,
},
{
Expand All @@ -157,8 +157,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image-~!@#$%^&*()<>?"|}:${tag}`,
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image-~!@#$%^&*()<>?"|}:${tag}`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
metadata:
Expand All @@ -168,8 +168,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: ubuntu-~!@#$%^&*()<>?"|:1.7.9 # kpt-set: ${image-~!@#$%^&*()<>?"|}:${tag}
- name: nginx
image: ubuntu-~!@#$%^&*()<>?"|:1.7.9 # kpt-set: ${image-~!@#$%^&*()<>?"|}:${tag}
`,
},
{
Expand All @@ -187,8 +187,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
Expand All @@ -199,8 +199,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
`,
},
{
Expand All @@ -218,8 +218,8 @@ spec:
template:
spec:
containers:
- image: irrelevant_value # kpt-set: ${image}:${tag}
name: nginx
- image: irrelevant_value # kpt-set: ${image}:${tag}
name: nginx
`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
Expand All @@ -230,8 +230,8 @@ spec:
template:
spec:
containers:
- image: irrelevant_value # kpt-set: ${image}:${tag}
name: nginx
- image: irrelevant_value # kpt-set: ${image}:${tag}
name: nginx
`,
errMsg: `values for setters [${tag}] must be provided`,
},
Expand All @@ -249,17 +249,17 @@ metadata:
name: nginx-deployment
spec:
images: # kpt-set: ${images}
- nginx
- ubuntu
- nginx
- ubuntu
`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
images: # kpt-set: ${images}
- ubuntu
- hbase
- ubuntu
- hbase
`,
},
{
Expand Down Expand Up @@ -351,8 +351,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
`,
expectedResources: `apiVersion: apps/v1
kind: Deployment
Expand All @@ -363,8 +363,8 @@ spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
- name: nginx
image: nginx:1.7.9 # kpt-set: ${image}:${tag}
`,
},
{
Expand Down Expand Up @@ -427,11 +427,11 @@ metadata:
namespace: "foo" # kpt-set: ${ns}
image: nginx:1.7.1 # kpt-set: ${image}:${tag}
env: # kpt-set: ${env}
- foo
- bar
- foo
- bar
roles: # kpt-set: ${roles}
- dev
- prod
- dev
- prod
`,
},
}
Expand All @@ -454,7 +454,7 @@ roles: # kpt-set: ${roles}
t.FailNow()
}

s := &ApplySetters{}
s := &Setters{}
node, err := kyaml.Parse(test.config)
if !assert.NoError(t, err) {
t.FailNow()
Expand Down
108 changes: 108 additions & 0 deletions functions/go/apply-setters/applysetters/setters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package applysetters

import (
"fmt"
"sigs.k8s.io/kustomize/kyaml/yaml"

"github.com/GoogleContainerTools/kpt-functions-sdk/go/fn"
)

const fnConfigKind = "ApplySetters"
const fnConfigApiVersion = "fn.kpt.dev/v1alpha1"

func ApplySetters(rl *fn.ResourceList) (bool, error) {
r := Setters{}
return r.Process(rl)
}

type Setters struct {
// Setters holds the user provided values for all the setters
Setters []Setter `yaml:"setters,omitempty" json:"setters,omitempty"`

// Results are the results of applying setter values
Results []*Result

// filePath file path of resource
filePath string
}

type Setter struct {
// Name is the name of the setter
Name string `yaml:"name" json:"name"`

// Value is the input value for setter
Value string `yaml:"value" json:"value"`
}

// Result holds result of search and replace operation
type Result struct {
// FilePath is the file path of the matching field
FilePath string

// FieldPath is field path of the matching field
FieldPath string

// Value of the matching field
Value string
}

// Config initializes Setters from a functionConfig fn.KubeObject
func (r *Setters) Config(functionConfig *fn.KubeObject) error {
if functionConfig.IsEmpty() {
return fmt.Errorf("FunctionConfig is missing. Expect `ApplySetters`")
}
if functionConfig.GetKind() != fnConfigKind || functionConfig.GetAPIVersion() != fnConfigApiVersion {
return fmt.Errorf("received functionConfig of kind %s and apiVersion %s, "+
"only functionConfig of kind %s and apiVersion %s is supported",
functionConfig.GetKind(), functionConfig.GetAPIVersion(), fnConfigKind, fnConfigApiVersion)
}
r.Setters = []Setter{}
if err := functionConfig.As(r); err != nil {
return fmt.Errorf("unable to convert functionConfig to %s:\n%w",
"setters", err)
}
return nil
}

// Process configures the setters and transforms them.
func (r *Setters) Process(rl *fn.ResourceList) (bool, error) {
if err := r.Config(rl.FunctionConfig); err != nil {
rl.LogResult(err)
return false, nil
}
transformedItems, err := r.Transform(rl.Items)
if err != nil {
rl.LogResult(err)
return false, nil
}
rl.Items = transformedItems
return true, nil
}

// Transform runs the setters filter in order to apply the setters - this
// does the actual work.
func (r *Setters) Transform(items []*fn.KubeObject) ([]*fn.KubeObject, error) {
var transformedItems []*fn.KubeObject
var nodes []*yaml.RNode

for _, obj := range items {
objRN, err := yaml.Parse(obj.String())
if err != nil {
return nil, err
}
nodes = append(nodes, objRN)
}

transformedNodes, err := r.Filter(nodes)
if err != nil {
return nil, err
}
for _, n := range transformedNodes {
obj, err := fn.ParseKubeObject([]byte(n.MustString()))
if err != nil {
return nil, err
}
transformedItems = append(transformedItems, obj)
}
return transformedItems, nil
}
2 changes: 0 additions & 2 deletions functions/go/apply-setters/generated/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading