Better starlark documentation

This commit is contained in:
Phillip Wittrock
2020-03-09 10:46:59 -07:00
parent 68a9389bfe
commit 7e8f8a649c
3 changed files with 211 additions and 4 deletions

View File

@@ -4,12 +4,22 @@
// Package starlark contains a kio.Filter which can be applied to resources to transform // Package starlark contains a kio.Filter which can be applied to resources to transform
// them through starlark program. // them through starlark program.
// //
// The resources are provided to the program through the global variable "resourceList". // Starlark has become a popular runtime embedding in go programs, especially for Kubernetes
// and data processing.
// Examples: https://github.com/cruise-automation/isopod, https://qri.io/docs/starlark/starlib,
// https://github.com/stripe/skycfg, https://github.com/k14s/ytt
//
// The resources are provided to the starlark program through the global variable "resourceList".
// "resourceList" is a dictionary containing an "items" field with a list of resources. // "resourceList" is a dictionary containing an "items" field with a list of resources.
// Changes to "resourceList" made by the starlark program will be reflected in the Filter output. // The starlark modified "resourceList" is the Filter output.
// //
// After being run through the starlark program, the filter will copy the comments from the input // After being run through the starlark program, the filter will copy the comments from the input
// resources to restore them after they are dropped due to the serialization. // resources to restore them -- due to them being dropped as a result of serializing the resources
// as starlark values.
//
// "resourceList" may also contain a "functionConfig" entry to configure the starlark script itself.
// Changes made by the starlark program to the "functionConfig" will be reflected in the
// Filter.FunctionConfig value.
// //
// The Filter will also format the output so that output has the preferred field ordering // The Filter will also format the output so that output has the preferred field ordering
// rather than an alphabetical field ordering. // rather than an alphabetical field ordering.

View File

@@ -6,10 +6,14 @@ package starlark_test
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os"
"path/filepath"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/starlark" "sigs.k8s.io/kustomize/kyaml/starlark"
"sigs.k8s.io/kustomize/kyaml/yaml"
) )
func ExampleFilter_Filter() { func ExampleFilter_Filter() {
@@ -91,3 +95,196 @@ run(resourceList["items"])
// - name: nginx // - name: nginx
// image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"} // image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
} }
func ExampleFilter_Filter_functionConfig() {
// input contains the items that will provided to the starlark program
input := bytes.NewBufferString(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-1
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-1"}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-2
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
`)
fc, err := yaml.Parse(`
kind: AnnotationSetter
spec:
value: "hello world"
`)
if err != nil {
log.Fatal(err)
}
// fltr transforms the input using a starlark program
fltr := &starlark.Filter{
Name: "annotate",
Program: `
def run(items, value):
for item in items:
item["metadata"]["annotations"]["foo"] = value
run(resourceList["items"], resourceList["functionConfig"]["spec"]["value"])
`,
FunctionConfig: fc,
}
// output contains the transformed resources
output := &bytes.Buffer{}
// run the fltr against the inputs using a kio.Pipeline
err = kio.Pipeline{
Inputs: []kio.Reader{&kio.ByteReader{Reader: input}},
Filters: []kio.Filter{fltr},
Outputs: []kio.Writer{&kio.ByteWriter{Writer: output}}}.Execute()
if err != nil {
log.Fatal(err)
}
fmt.Println(output.String())
// Output:
// apiVersion: apps/v1
// kind: Deployment
// metadata:
// name: deployment-1
// annotations:
// foo: hello world
// spec:
// template:
// spec:
// containers:
// - name: nginx
// image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-1"}
//---
// apiVersion: apps/v1
// kind: Deployment
// metadata:
// name: deployment-2
// annotations:
// foo: hello world
// spec:
// template:
// spec:
// containers:
// - name: nginx
// image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
}
// ExampleFilter_Filter_file applies a starlark program in a local file to a collection of
// resource configuration read from a directory.
func ExampleFilter_Filter_file() {
// setup the configuration
d, err := ioutil.TempDir("", "")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(d)
err = ioutil.WriteFile(filepath.Join(d, "deploy1.yaml"), []byte(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-1
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-1"}
`), 0600)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(filepath.Join(d, "deploy2.yaml"), []byte(`
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-2
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
`), 0600)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(filepath.Join(d, "annotate.star"), []byte(`
def run(items):
for item in items:
item["metadata"]["annotations"]["foo"] = "bar"
run(resourceList["items"])
`), 0600)
if err != nil {
log.Fatal(err)
}
fltr := &starlark.Filter{
Name: "annotate",
Path: filepath.Join(d, "annotate.star"),
}
// output contains the transformed resources
output := &bytes.Buffer{}
// run the fltr against the inputs using a kio.Pipeline
err = kio.Pipeline{
Inputs: []kio.Reader{&kio.LocalPackageReader{PackagePath: d}},
Filters: []kio.Filter{fltr},
Outputs: []kio.Writer{&kio.ByteWriter{
Writer: output,
ClearAnnotations: []string{"config.kubernetes.io/path"},
}}}.Execute()
if err != nil {
log.Fatal(err)
}
fmt.Println(output.String())
// Output:
// apiVersion: apps/v1
// kind: Deployment
// metadata:
// name: deployment-1
// annotations:
// foo: bar
// spec:
// template:
// spec:
// containers:
// - name: nginx
// image: nginx:1.8.1 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-1"}
//---
// apiVersion: apps/v1
// kind: Deployment
// metadata:
// name: deployment-2
// annotations:
// foo: bar
// spec:
// template:
// spec:
// containers:
// - name: nginx
// image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
}

View File

@@ -16,7 +16,7 @@ import (
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
func TestStarlarkFilter_Filter(t *testing.T) { func TestFilter_Filter(t *testing.T) {
var tests = []struct { var tests = []struct {
name string name string
input string input string