diff --git a/starlark/types/attribute.go b/starlark/types/attribute.go index 847fbf7..c2ab48a 100644 --- a/starlark/types/attribute.go +++ b/starlark/types/attribute.go @@ -155,9 +155,35 @@ func (c *Attribute) Index(i int) starlark.Value { return NewAttributeWithPath(c.r, *c.t.ListElementType(), c.name, path) } + if c.t.IsMapType() { + return NewAttributeWithPath(c.r, c.t, c.name, path) + } + return starlark.None } +// Get honors the starlark.Mapping interface. +func (c *Attribute) Get(key starlark.Value) (v starlark.Value, found bool, err error) { + switch vKey := key.(type) { + case starlark.Int: + if !c.t.IsSetType() && !c.t.IsListType() && !c.t.IsMapType() { + return nil, false, fmt.Errorf("%s does not support index", c.name) + } + + index, _ := vKey.Int64() + return c.Index(int(index)), true, nil + case starlark.String: + if !c.t.IsMapType() { + return nil, false, fmt.Errorf("%s it's not a dict", c.name) + } + + path := fmt.Sprintf("%s.%s", c.path, vKey.GoString()) + return NewAttributeWithPath(c.r, c.t, c.name, path), true, nil + default: + return nil, false, fmt.Errorf("%s: unexpected key type %s", c.name, key.Type()) + } +} + // Len honors the starlark.Indexable interface. func (c *Attribute) Len() int { if !c.t.IsSetType() && !c.t.IsListType() { diff --git a/starlark/types/testdata/attribute.star b/starlark/types/testdata/attribute.star index bc19ad6..961f58f 100644 --- a/starlark/types/testdata/attribute.star +++ b/starlark/types/testdata/attribute.star @@ -47,6 +47,12 @@ assert.eq(str(cluster.master_auth.client_certificate), "${google_container_clust # attr non-object assert.fails(lambda: web.ami.foo, "Attribute it's not a object") - # fn wrapping assert.eq(str(fn("base64encode", web.ami)), "${base64encode(data.aws_ami.id_2.id)}") + +# attribute of dict +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}")