79
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/context.go
generated
vendored
Normal file
79
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/context.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package starlark
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"go.starlark.net/starlark"
|
||||
"go.starlark.net/starlarkstruct"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/qri-io/starlib/util"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
resourceList starlark.Value
|
||||
}
|
||||
|
||||
func (c *Context) predeclared() (starlark.StringDict, error) {
|
||||
e, err := env()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oa, err := oa()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dict := starlark.StringDict{
|
||||
"resource_list": c.resourceList,
|
||||
"open_api": oa,
|
||||
"environment": e,
|
||||
}
|
||||
|
||||
return starlark.StringDict{
|
||||
"ctx": starlarkstruct.FromStringDict(starlarkstruct.Default, dict),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func oa() (starlark.Value, error) {
|
||||
return interfaceToValue(openapi.Schema())
|
||||
}
|
||||
|
||||
func env() (starlark.Value, error) {
|
||||
env := map[string]interface{}{}
|
||||
for _, e := range os.Environ() {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
if len(pair) < 2 {
|
||||
continue
|
||||
}
|
||||
env[pair[0]] = pair[1]
|
||||
}
|
||||
value, err := util.Marshal(env)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func interfaceToValue(i interface{}) (starlark.Value, error) {
|
||||
b, err := json.Marshal(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var in map[string]interface{}
|
||||
if err := yaml.Unmarshal(b, &in); err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
value, err := util.Marshal(in)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
36
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/doc.go
generated
vendored
Normal file
36
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/doc.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// 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
|
||||
package starlark
|
||||
181
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/starlark.go
generated
vendored
Normal file
181
vendor/sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark/starlark.go
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package starlark
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"go.starlark.net/starlark"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/qri-io/starlib/util"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/filters"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
// Filter transforms a set of resources through the provided program
|
||||
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
|
||||
}
|
||||
|
||||
func (sf *Filter) String() string {
|
||||
return fmt.Sprintf(
|
||||
"name: %v path: %v url: %v program: %v", sf.Name, sf.Path, sf.URL, sf.Program)
|
||||
}
|
||||
|
||||
func (sf *Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
err := sf.setup()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sf.FunctionFilter.Run = sf.Run
|
||||
|
||||
return sf.FunctionFilter.Filter(nodes)
|
||||
}
|
||||
|
||||
func (sf *Filter) setup() error {
|
||||
if (sf.URL != "" && sf.Path != "") ||
|
||||
(sf.URL != "" && sf.Program != "") ||
|
||||
(sf.Path != "" && sf.Program != "") {
|
||||
return errors.Errorf("Filter Path, Program and URL are mutually exclusive")
|
||||
}
|
||||
|
||||
// read the program from a file
|
||||
if sf.Path != "" {
|
||||
b, err := ioutil.ReadFile(sf.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sf.Program = string(b)
|
||||
}
|
||||
|
||||
// read the program from a URL
|
||||
if sf.URL != "" {
|
||||
err := func() error {
|
||||
resp, err := http.Get(sf.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sf.Program = string(b)
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sf *Filter) Run(reader io.Reader, writer io.Writer) error {
|
||||
// retain map of inputs to outputs by id so if the name is changed by the
|
||||
// starlark program, we are able to match the same resources
|
||||
value, err := sf.readResourceList(reader)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// run the starlark as program as transformation function
|
||||
thread := &starlark.Thread{Name: sf.Name}
|
||||
|
||||
ctx := &Context{resourceList: value}
|
||||
pd, err := ctx.predeclared()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
_, err = starlark.ExecFile(thread, sf.Name, sf.Program, pd)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
return sf.writeResourceList(value, writer)
|
||||
}
|
||||
|
||||
// inputToResourceList transforms input into a starlark.Value
|
||||
func (sf *Filter) readResourceList(reader io.Reader) (starlark.Value, error) {
|
||||
// read and parse the inputs
|
||||
rl := bytes.Buffer{}
|
||||
_, err := rl.ReadFrom(reader)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
rn, err := yaml.Parse(rl.String())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
|
||||
// convert to a starlark value
|
||||
b, err := yaml.Marshal(rn.Document()) // convert to bytes
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
var in map[string]interface{}
|
||||
err = yaml.Unmarshal(b, &in) // convert to map[string]interface{}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
return util.Marshal(in) // convert to starlark value
|
||||
}
|
||||
|
||||
// resourceListToOutput converts the output of the starlark program to the filter output
|
||||
func (sf *Filter) writeResourceList(value starlark.Value, writer io.Writer) error {
|
||||
// convert the modified resourceList back into a slice of RNodes
|
||||
// by first converting to a map[string]interface{}
|
||||
out, err := util.Unmarshal(value)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
b, err := yaml.Marshal(out)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
rl, err := yaml.Parse(string(b))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
// preserve the comments from the input
|
||||
items, err := rl.Pipe(yaml.Lookup("items"))
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
err = items.VisitElements(func(node *yaml.RNode) error {
|
||||
// starlark will serialize the resources sorting the fields alphabetically,
|
||||
// format them to have a better ordering
|
||||
_, err := filters.FormatFilter{}.Filter([]*yaml.RNode{node})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
s, err := rl.String()
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
|
||||
_, err = writer.Write([]byte(s))
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user