mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Support publishing starlark functions from urls
This commit is contained in:
@@ -563,6 +563,90 @@ metadata:
|
||||
"deployment.yaml": `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
a-bool-value: true
|
||||
a-int-value: 2
|
||||
a-string-value: a
|
||||
`,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "starlark_function_url",
|
||||
args: func(d string) []string {
|
||||
return []string{
|
||||
"--enable-star", "--star-url", "https://storage.googleapis.com/kustomize-starlark-functions/annotate.star",
|
||||
"--star-name", "annotate",
|
||||
"--", "stringValue=a", "intValue=2", "boolValue=true",
|
||||
}
|
||||
},
|
||||
files: func(d string) map[string]string {
|
||||
return map[string]string{
|
||||
"deployment.yaml": `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
`,
|
||||
}
|
||||
},
|
||||
expectedFiles: func(d string) map[string]string {
|
||||
return map[string]string{
|
||||
"deployment.yaml": `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
a-bool-value: true
|
||||
a-int-value: 2
|
||||
a-string-value: a
|
||||
`,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "starlark_function_url_config",
|
||||
args: func(d string) []string {
|
||||
return []string{"--enable-star"}
|
||||
},
|
||||
files: func(d string) map[string]string {
|
||||
return map[string]string{
|
||||
"config.yaml": `
|
||||
apiVersion: example.com/v1alpha1
|
||||
kind: Input
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
a-bool-value: true
|
||||
a-int-value: 2
|
||||
a-string-value: a
|
||||
config.kubernetes.io/function: |
|
||||
starlark:
|
||||
url: https://storage.googleapis.com/kustomize-starlark-functions/annotate.star
|
||||
name: fn
|
||||
data:
|
||||
boolValue: true
|
||||
intValue: 2
|
||||
stringValue: a
|
||||
`,
|
||||
"deployment.yaml": `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
`,
|
||||
}
|
||||
},
|
||||
expectedFiles: func(d string) map[string]string {
|
||||
return map[string]string{
|
||||
"deployment.yaml": `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: foo
|
||||
annotations:
|
||||
@@ -607,7 +691,7 @@ metadata:
|
||||
|
||||
err = cmd.Run()
|
||||
if tt.expectedErr != "" {
|
||||
if !assert.Contains(t, stdErr.String(), tt.expectedErr) {
|
||||
if !assert.Contains(t, stdErr.String(), tt.expectedErr, stdErr.String()) {
|
||||
t.FailNow()
|
||||
}
|
||||
return
|
||||
@@ -618,10 +702,10 @@ metadata:
|
||||
|
||||
for path, data := range tt.expectedFiles(binDir) {
|
||||
b, err := ioutil.ReadFile(path)
|
||||
if !assert.NoError(t, err) {
|
||||
if !assert.NoError(t, err, stdErr.String()) {
|
||||
t.FailNow()
|
||||
}
|
||||
if !assert.Equal(t, strings.TrimSpace(data), strings.TrimSpace(string(b))) {
|
||||
if !assert.Equal(t, strings.TrimSpace(data), strings.TrimSpace(string(b)), stdErr.String()) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
7
cmd/config/internal/commands/e2e/starlark/annotate.star
Normal file
7
cmd/config/internal/commands/e2e/starlark/annotate.star
Normal file
@@ -0,0 +1,7 @@
|
||||
def run(r, fc):
|
||||
for resource in r:
|
||||
resource["metadata"]["annotations"]["a-string-value"] = fc["data"]["stringValue"]
|
||||
resource["metadata"]["annotations"]["a-int-value"] = fc["data"]["intValue"]
|
||||
resource["metadata"]["annotations"]["a-bool-value"] = fc["data"]["boolValue"]
|
||||
|
||||
run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])
|
||||
@@ -50,6 +50,8 @@ func GetRunFnRunner(name string) *RunFnRunner {
|
||||
&r.EnableStar, "enable-star", false, "enable support for starlark functions. (Alpha)")
|
||||
r.Command.Flags().StringVar(
|
||||
&r.StarPath, "star-path", "", "run a starlark script as a function. (Alpha)")
|
||||
r.Command.Flags().StringVar(
|
||||
&r.StarURL, "star-url", "", "run a starlark script as a function. (Alpha)")
|
||||
r.Command.Flags().StringVar(
|
||||
&r.StarName, "star-name", "", "name of starlark program. (Alpha)")
|
||||
|
||||
@@ -80,6 +82,7 @@ type RunFnRunner struct {
|
||||
Image string
|
||||
EnableStar bool
|
||||
StarPath string
|
||||
StarURL string
|
||||
StarName string
|
||||
EnableExec bool
|
||||
ExecPath string
|
||||
@@ -98,7 +101,8 @@ func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
|
||||
// Functions to run.
|
||||
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
|
||||
[]*yaml.RNode, error) {
|
||||
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" {
|
||||
|
||||
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -126,26 +130,36 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else if r.EnableStar && r.StarPath != "" {
|
||||
} else if r.EnableStar && (r.StarPath != "" || r.StarURL != "") {
|
||||
// create the function spec to set as an annotation
|
||||
fn, err = yaml.Parse(`starlark: {}`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = fn.PipeE(
|
||||
yaml.Lookup("starlark"),
|
||||
yaml.SetField("path", yaml.NewScalarRNode(r.StarPath)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if r.StarPath != "" {
|
||||
err = fn.PipeE(
|
||||
yaml.Lookup("starlark"),
|
||||
yaml.SetField("path", yaml.NewScalarRNode(r.StarPath)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if r.StarURL != "" {
|
||||
err = fn.PipeE(
|
||||
yaml.Lookup("starlark"),
|
||||
yaml.SetField("url", yaml.NewScalarRNode(r.StarURL)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
err = fn.PipeE(
|
||||
yaml.Lookup("starlark"),
|
||||
yaml.SetField("name", yaml.NewScalarRNode(r.StarName)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if r.EnableExec && r.ExecPath != "" {
|
||||
// create the function spec to set as an annotation
|
||||
fn, err = yaml.Parse(`exec: {}`)
|
||||
@@ -231,8 +245,8 @@ func toStorageMounts(mounts []string) []runtimeutil.StorageMount {
|
||||
}
|
||||
|
||||
func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
if !r.EnableStar && r.StarPath != "" {
|
||||
return errors.Errorf("must specify --enable-star with --star-path")
|
||||
if !r.EnableStar && (r.StarPath != "" || r.StarURL != "") {
|
||||
return errors.Errorf("must specify --enable-star with --star-path and --star-url")
|
||||
}
|
||||
|
||||
if !r.EnableExec && r.ExecPath != "" {
|
||||
@@ -240,7 +254,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if c.ArgsLenAtDash() >= 0 && r.Image == "" &&
|
||||
!(r.EnableStar && r.StarPath != "") && !(r.EnableExec && r.ExecPath != "") {
|
||||
!(r.EnableStar && (r.StarPath != "" || r.StarURL != "")) && !(r.EnableExec && r.ExecPath != "") {
|
||||
return errors.Errorf("must specify --image")
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ type StarlarkSpec struct {
|
||||
|
||||
// Path specifies a path to a starlark script
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
|
||||
// URL specifies a url containing a starlark script
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
}
|
||||
|
||||
// StorageMount represents a container's mounted storage option(s)
|
||||
|
||||
@@ -50,9 +50,9 @@ func (sf *Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
}
|
||||
|
||||
func (sf *Filter) setup() error {
|
||||
if sf.URL != "" && sf.Path != "" ||
|
||||
sf.URL != "" && sf.Program != "" ||
|
||||
sf.Path != "" && sf.Program != "" {
|
||||
if (sf.URL != "" && sf.Path != "") ||
|
||||
(sf.URL != "" && sf.Program != "") ||
|
||||
(sf.Path != "" && sf.Program != "") {
|
||||
return errors.Errorf("Filter Path, Program and URL are mutually exclusive")
|
||||
}
|
||||
|
||||
|
||||
@@ -356,25 +356,29 @@ func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode) (kio.Filter
|
||||
cf.Exec.DeferFailure = spec.DeferFailure
|
||||
return cf, nil
|
||||
}
|
||||
if r.EnableStarlark && spec.Starlark.Path != "" {
|
||||
if r.EnableStarlark && (spec.Starlark.Path != "" || spec.Starlark.URL != "") {
|
||||
// the script path is relative to the function config file
|
||||
m, err := api.GetMeta()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err)
|
||||
}
|
||||
p := m.Annotations[kioutil.PathAnnotation]
|
||||
spec.Starlark.Path = path.Clean(spec.Starlark.Path)
|
||||
if path.IsAbs(spec.Starlark.Path) {
|
||||
return nil, errors.Errorf(
|
||||
"absolute function path %s not allowed", spec.Starlark.Path)
|
||||
}
|
||||
if strings.HasPrefix(spec.Starlark.Path, "..") {
|
||||
return nil, errors.Errorf(
|
||||
"function path %s not allowed to start with ../", spec.Starlark.Path)
|
||||
}
|
||||
p = path.Join(r.Path, path.Dir(p), spec.Starlark.Path)
|
||||
|
||||
sf := &starlark.Filter{Name: spec.Starlark.Name, Path: p}
|
||||
var p string
|
||||
if spec.Starlark.Path != "" {
|
||||
p = m.Annotations[kioutil.PathAnnotation]
|
||||
spec.Starlark.Path = path.Clean(spec.Starlark.Path)
|
||||
if path.IsAbs(spec.Starlark.Path) {
|
||||
return nil, errors.Errorf(
|
||||
"absolute function path %s not allowed", spec.Starlark.Path)
|
||||
}
|
||||
if strings.HasPrefix(spec.Starlark.Path, "..") {
|
||||
return nil, errors.Errorf(
|
||||
"function path %s not allowed to start with ../", spec.Starlark.Path)
|
||||
}
|
||||
p = path.Join(r.Path, path.Dir(p), spec.Starlark.Path)
|
||||
}
|
||||
|
||||
sf := &starlark.Filter{Name: spec.Starlark.Name, Path: p, URL: spec.Starlark.URL}
|
||||
|
||||
sf.FunctionConfig = api
|
||||
sf.GlobalScope = r.GlobalScope
|
||||
|
||||
Reference in New Issue
Block a user