Files
kustomize/kyaml/fn/runtime/starlark/starlark_test.go

538 lines
12 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package starlark
import (
"bytes"
"fmt"
"os"
"strings"
"testing"
"github.com/go-errors/errors"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestFilter_Filter(t *testing.T) {
var tests = []struct {
name string
input string
functionConfig string
script string
expected string
expectedFunctionConfig string
env map[string]string
}{
{
name: "add_annotation",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
# set the foo annotation on each resource
def run(r):
for resource in r:
resource["metadata"]["annotations"]["foo"] = "bar"
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: bar
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
},
{
name: "add_annotation_from_env",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
def run(r):
for resource in r:
resource["metadata"]["annotations"]["foo"] = ctx.environment["ANNOTATION"]
run(ctx.resource_list["items"])
`,
env: map[string]string{"ANNOTATION": "annotation-value"},
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: annotation-value
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
},
{
name: "add_annotation_from_open_api",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
def run(r):
for resource in r:
resource["metadata"]["annotations"]["foo"] = ctx.open_api["definitions"]["io.k8s.api.apps.v1.Deployment"]["description"]
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: Deployment enables declarative updates for Pods and ReplicaSets.
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
},
{
name: "update_annotation",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: baz
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
# set the foo annotation on each resource
def run(r):
for resource in r:
resource["metadata"]["annotations"]["foo"] = "bar"
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: bar
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
},
{
name: "delete_annotation",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: baz
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
# set the foo annotation on each resource
def run(r):
for resource in r:
resource["metadata"]["annotations"].pop("foo")
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
},
{
name: "update_annotation_multiple",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
annotations:
foo: baz
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-2
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
# set the foo annotation on each resource
def run(r):
for resource in r:
resource["metadata"]["annotations"]["foo"] = "bar"
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
annotations:
foo: bar
internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-2
annotations:
foo: bar
internal.config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}`,
},
{
name: "add_resource",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
script: `
def run(r):
d = {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "nginx-deployment-2",
},
}
r.append(d)
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
annotations:
internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-2
annotations:
internal.config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment-2.yaml'
`,
},
{
name: "remove_resource",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-2
`,
script: `
def run(r):
r.pop()
run(ctx.resource_list["items"])
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-1
annotations:
internal.config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment-1.yaml'
`,
},
{
name: "functionConfig",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
functionConfig: `
kind: Script
spec:
value: "hello world"
`,
script: `
# set the foo annotation on each resource
def run(r, an):
for resource in r:
resource["metadata"]["annotations"]["foo"] = an
an = ctx.resource_list["functionConfig"]["spec"]["value"]
run(ctx.resource_list["items"], an)
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: hello world
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
expectedFunctionConfig: `
kind: Script
spec:
value: "hello world"
`,
},
{
name: "functionConfig_update_functionConfig",
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
functionConfig: `
kind: Script
spec:
value: "hello world"
`,
script: `
# set the foo annotation on each resource
def run(r, an):
for resource in r:
resource["metadata"]["annotations"]["foo"] = an
an = ctx.resource_list["functionConfig"]["spec"]["value"]
run(ctx.resource_list["items"], an)
ctx.resource_list["functionConfig"]["spec"]["value"] = "updated"
`,
expected: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
annotations:
foo: hello world
internal.config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
config.kubernetes.io/path: 'deployment_nginx-deployment.yaml'
spec:
template:
spec:
containers:
- name: nginx
# head comment
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image"}
`,
expectedFunctionConfig: `
kind: Script
spec:
value: "hello world"
`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
for k, v := range test.env {
os.Setenv(k, v)
}
f := &Filter{Name: test.name, Program: test.script}
if test.functionConfig != "" {
fc, err := yaml.Parse(test.functionConfig)
if !assert.NoError(t, err) {
t.FailNow()
}
f.FunctionConfig = fc
}
r := &kio.ByteReader{Reader: bytes.NewBufferString(test.input)}
o := &bytes.Buffer{}
w := &kio.ByteWriter{Writer: o}
p := kio.Pipeline{
Inputs: []kio.Reader{r},
Filters: []kio.Filter{f},
Outputs: []kio.Writer{w},
}
err := p.Execute()
if !assert.NoError(t, err) {
if e, ok := err.(*errors.Error); ok {
fmt.Fprintf(os.Stderr, "%s\n", e.Stack())
}
t.FailNow()
}
if !assert.Equal(t, strings.TrimSpace(test.expected), strings.TrimSpace(o.String())) {
t.FailNow()
}
if test.expectedFunctionConfig != "" {
if !assert.Equal(t,
strings.TrimSpace(test.expectedFunctionConfig),
strings.TrimSpace(f.FunctionConfig.MustString())) {
t.FailNow()
}
}
})
}
}