From 476219624e38ce860b305151002b17ff815a391b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ximo=20Cuadros?= Date: Fri, 22 May 2020 15:31:58 +0200 Subject: [PATCH] starlark/types: ref function --- starlark/runtime/runtime.go | 1 + starlark/types/attribute.go | 34 +++++++++++++++++++++++ starlark/types/provider_test.go | 1 + starlark/types/testdata/attribute.star | 10 +++++++ starlark/types/testdata/examples/ref.star | 12 ++++++++ 5 files changed, 58 insertions(+) create mode 100644 starlark/types/testdata/examples/ref.star diff --git a/starlark/runtime/runtime.go b/starlark/runtime/runtime.go index 7092dd2..bbb1f70 100644 --- a/starlark/runtime/runtime.go +++ b/starlark/runtime/runtime.go @@ -58,6 +58,7 @@ func NewRuntime(pm *terraform.PluginManager) *Runtime { predeclared["validate"] = types.BuiltinValidate() predeclared["hcl"] = types.BuiltinHCL() predeclared["fn"] = types.BuiltinFunctionAttribute() + predeclared["ref"] = types.BuiltinRef() predeclared["evaluate"] = types.BuiltinEvaluate(predeclared) predeclared["struct"] = starlark.NewBuiltin("struct", starlarkstruct.Make) predeclared["module"] = starlark.NewBuiltin("module", starlarkstruct.MakeModule) diff --git a/starlark/types/attribute.go b/starlark/types/attribute.go index c2ab48a..2e7e37a 100644 --- a/starlark/types/attribute.go +++ b/starlark/types/attribute.go @@ -10,6 +10,40 @@ import ( // sTring alias required to avoid name collision with the method String. type sString = starlark.String +// BuiltinRef returns a starlak.Builtin function to generate a reference to a +// resource argument. +// +// outline: types +// functions: +// ref(resource, argument) string +// Returns a reference to a resource argument. +// params: +// resource +// resource to be referenced. +// field string +// field to be referenced. +// +// examples: +// ref.star +// +func BuiltinRef() starlark.Value { + return starlark.NewBuiltin("ref", func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { + var resource *Resource + var argument string + err := starlark.UnpackArgs("ref", args, kwargs, "resource", &resource, "argument", &argument) + if err != nil { + return nil, err + } + + attr, ok := resource.block.Attributes[argument] + if !ok { + return nil, fmt.Errorf("%s has no .%s field", resource, argument) + } + + return NewAttribute(resource, attr.Type, argument), nil + }) +} + // Attribute is a reference to an argument of a Resource. Used mainly // for Computed arguments of Resources. // diff --git a/starlark/types/provider_test.go b/starlark/types/provider_test.go index 8dd9dae..7870cb3 100644 --- a/starlark/types/provider_test.go +++ b/starlark/types/provider_test.go @@ -83,6 +83,7 @@ func doTestPrint(t *testing.T, filename string, print func(*starlark.Thread, str predeclared["hcl"] = BuiltinHCL() predeclared["validate"] = BuiltinValidate() predeclared["fn"] = BuiltinFunctionAttribute() + predeclared["ref"] = BuiltinRef() predeclared["evaluate"] = BuiltinEvaluate(predeclared) predeclared["struct"] = starlark.NewBuiltin("struct", starlarkstruct.Make) predeclared["module"] = starlark.NewBuiltin("module", starlarkstruct.MakeModule) diff --git a/starlark/types/testdata/attribute.star b/starlark/types/testdata/attribute.star index 961f58f..baca713 100644 --- a/starlark/types/testdata/attribute.star +++ b/starlark/types/testdata/attribute.star @@ -56,3 +56,13 @@ k8s = tf.provider("kubernetes") secret = k8s.data.secret("foo") assert.eq(str(secret.data["qux"]), "${data.kubernetes_secret.foo.data.qux}") assert.eq(str(secret.data["qux"][0]), "${data.kubernetes_secret.foo.data.qux.0}") + +# ref +secret = k8s.resource.secret("foo") +secret.metadata.name = "foo" +secret.type = "kubernetes.io/dockerconfigjson" +assert.eq(str(ref(secret, "type")), "${kubernetes_secret.foo.type}") +assert.eq(str(ref(secret.metadata, "name")), "${kubernetes_secret.foo.metadata.0.name}") + +# ref to non-exits +assert.fails(lambda: ref(secret, "foo"), "Resource has no .foo field") \ No newline at end of file diff --git a/starlark/types/testdata/examples/ref.star b/starlark/types/testdata/examples/ref.star new file mode 100644 index 0000000..0b3a0aa --- /dev/null +++ b/starlark/types/testdata/examples/ref.star @@ -0,0 +1,12 @@ +# Non-computed arguments are passed by value to one argument to another +# in some cases may be required to make a referece to and relay in the HCL +# interpolation. + +aws = tf.provider("aws") + +instance = aws.resource.instance("foo") +instance.ami = "foo" + +print(ref(instance, "ami")) +# Output: +# ${aws_instance.foo.ami} \ No newline at end of file