mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Merge pull request #2470 from pwittrock/master
Support publishing starlark functions from urls
This commit is contained in:
@@ -563,6 +563,90 @@ metadata:
|
|||||||
"deployment.yaml": `
|
"deployment.yaml": `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
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:
|
metadata:
|
||||||
name: foo
|
name: foo
|
||||||
annotations:
|
annotations:
|
||||||
@@ -607,7 +691,7 @@ metadata:
|
|||||||
|
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
if tt.expectedErr != "" {
|
if tt.expectedErr != "" {
|
||||||
if !assert.Contains(t, stdErr.String(), tt.expectedErr) {
|
if !assert.Contains(t, stdErr.String(), tt.expectedErr, stdErr.String()) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -618,10 +702,10 @@ metadata:
|
|||||||
|
|
||||||
for path, data := range tt.expectedFiles(binDir) {
|
for path, data := range tt.expectedFiles(binDir) {
|
||||||
b, err := ioutil.ReadFile(path)
|
b, err := ioutil.ReadFile(path)
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err, stdErr.String()) {
|
||||||
t.FailNow()
|
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()
|
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.EnableStar, "enable-star", false, "enable support for starlark functions. (Alpha)")
|
||||||
r.Command.Flags().StringVar(
|
r.Command.Flags().StringVar(
|
||||||
&r.StarPath, "star-path", "", "run a starlark script as a function. (Alpha)")
|
&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.Command.Flags().StringVar(
|
||||||
&r.StarName, "star-name", "", "name of starlark program. (Alpha)")
|
&r.StarName, "star-name", "", "name of starlark program. (Alpha)")
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ type RunFnRunner struct {
|
|||||||
Image string
|
Image string
|
||||||
EnableStar bool
|
EnableStar bool
|
||||||
StarPath string
|
StarPath string
|
||||||
|
StarURL string
|
||||||
StarName string
|
StarName string
|
||||||
EnableExec bool
|
EnableExec bool
|
||||||
ExecPath string
|
ExecPath string
|
||||||
@@ -98,7 +101,8 @@ func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
|
|||||||
// Functions to run.
|
// Functions to run.
|
||||||
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
|
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
|
||||||
[]*yaml.RNode, error) {
|
[]*yaml.RNode, error) {
|
||||||
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" {
|
|
||||||
|
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" && r.StarURL == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,26 +130,36 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []
|
|||||||
return nil, err
|
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
|
// create the function spec to set as an annotation
|
||||||
fn, err = yaml.Parse(`starlark: {}`)
|
fn, err = yaml.Parse(`starlark: {}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fn.PipeE(
|
if r.StarPath != "" {
|
||||||
yaml.Lookup("starlark"),
|
err = fn.PipeE(
|
||||||
yaml.SetField("path", yaml.NewScalarRNode(r.StarPath)))
|
yaml.Lookup("starlark"),
|
||||||
if err != nil {
|
yaml.SetField("path", yaml.NewScalarRNode(r.StarPath)))
|
||||||
return nil, err
|
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(
|
err = fn.PipeE(
|
||||||
yaml.Lookup("starlark"),
|
yaml.Lookup("starlark"),
|
||||||
yaml.SetField("name", yaml.NewScalarRNode(r.StarName)))
|
yaml.SetField("name", yaml.NewScalarRNode(r.StarName)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if r.EnableExec && r.ExecPath != "" {
|
} else if r.EnableExec && r.ExecPath != "" {
|
||||||
// create the function spec to set as an annotation
|
// create the function spec to set as an annotation
|
||||||
fn, err = yaml.Parse(`exec: {}`)
|
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 {
|
func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
|
||||||
if !r.EnableStar && r.StarPath != "" {
|
if !r.EnableStar && (r.StarPath != "" || r.StarURL != "") {
|
||||||
return errors.Errorf("must specify --enable-star with --star-path")
|
return errors.Errorf("must specify --enable-star with --star-path and --star-url")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !r.EnableExec && r.ExecPath != "" {
|
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 == "" &&
|
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")
|
return errors.Errorf("must specify --image")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ type StarlarkSpec struct {
|
|||||||
|
|
||||||
// Path specifies a path to a starlark script
|
// Path specifies a path to a starlark script
|
||||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
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)
|
// 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 {
|
func (sf *Filter) setup() error {
|
||||||
if sf.URL != "" && sf.Path != "" ||
|
if (sf.URL != "" && sf.Path != "") ||
|
||||||
sf.URL != "" && sf.Program != "" ||
|
(sf.URL != "" && sf.Program != "") ||
|
||||||
sf.Path != "" && sf.Program != "" {
|
(sf.Path != "" && sf.Program != "") {
|
||||||
return errors.Errorf("Filter Path, Program and URL are mutually exclusive")
|
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
|
cf.Exec.DeferFailure = spec.DeferFailure
|
||||||
return cf, nil
|
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
|
// the script path is relative to the function config file
|
||||||
m, err := api.GetMeta()
|
m, err := api.GetMeta()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err)
|
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.FunctionConfig = api
|
||||||
sf.GlobalScope = r.GlobalScope
|
sf.GlobalScope = r.GlobalScope
|
||||||
|
|||||||
Reference in New Issue
Block a user