Documentation ¶
Overview ¶
Package starlark contains a kio.Filter which can be applied to resources to transform them through starlark program.
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. The starlark modified "resourceList" is the Filter output.
After being run through the starlark program, the filter will copy the comments from the input 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 rather than an alphabetical field ordering.
The resourceList variable adheres to the kustomize function spec as specified by: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md
All items in the resourceList are resources represented as starlark dictionaries/ The items in the resourceList respect the io spec specified by: https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/config-io.md
The starlark language spec can be found here: https://github.com/google/starlark-go/blob/master/doc/spec.md
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Filter ¶
type Filter struct { Name string // Program is a starlark script which will be run against the resources Program string // URL is the url of a starlark program to fetch and run URL string // Path is the path to a starlark program to read and run Path string runtimeutil.FunctionFilter }
Filter transforms a set of resources through the provided program
func (*Filter) Filter ¶
Example ¶
package main import ( "bytes" "fmt" "log" "sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark" "sigs.k8s.io/kustomize/kyaml/kio" ) func main() { // 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"} `) // fltr transforms the input using a starlark program fltr := &starlark.Filter{ Name: "annotate", Program: ` def run(items): for item in items: item["metadata"]["annotations"]["foo"] = "bar" run(ctx.resource_list["items"]) `, } // 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.Println(err) } fmt.Println(output.String()) }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: deployment-1 annotations: foo: bar internal.config.kubernetes.io/path: 'deployment_deployment-1.yaml' config.kubernetes.io/path: 'deployment_deployment-1.yaml' 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 internal.config.kubernetes.io/path: 'deployment_deployment-2.yaml' config.kubernetes.io/path: 'deployment_deployment-2.yaml' spec: template: spec: containers: - name: nginx image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}
Example (File) ¶
ExampleFilter_Filter_file applies a starlark program in a local file to a collection of resource configuration read from a directory.
package main import ( "bytes" "fmt" "io/ioutil" "log" "os" "path/filepath" "sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" ) func main() { // setup the configuration d, err := ioutil.TempDir("", "") if err != nil { log.Println(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.Println(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.Println(err) } err = ioutil.WriteFile(filepath.Join(d, "annotate.star"), []byte(` def run(items): for item in items: item["metadata"]["annotations"]["foo"] = "bar" run(ctx.resource_list["items"]) `), 0600) if err != nil { log.Println(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{ kioutil.PathAnnotation, kioutil.LegacyPathAnnotation, }, }}}.Execute() if err != nil { log.Println(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"}
Example (FunctionConfig) ¶
package main import ( "bytes" "fmt" "log" "sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil" "sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" ) func main() { // 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.Println(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(ctx.resource_list["items"], ctx.resource_list["functionConfig"]["spec"]["value"]) `, FunctionFilter: runtimeutil.FunctionFilter{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.Println(err) } fmt.Println(output.String()) }
Output: apiVersion: apps/v1 kind: Deployment metadata: name: deployment-1 annotations: foo: hello world internal.config.kubernetes.io/path: 'deployment_deployment-1.yaml' config.kubernetes.io/path: 'deployment_deployment-1.yaml' 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 internal.config.kubernetes.io/path: 'deployment_deployment-2.yaml' config.kubernetes.io/path: 'deployment_deployment-2.yaml' spec: template: spec: containers: - name: nginx image: nginx:1.7.9 # {"$ref": "#/definitions/io.k8s.cli.substitutions.image-2"}