mirror of
https://github.com/mcuadros/ascode
synced 2024-05-08 08:36:15 +02:00
starlark/types: ResourceCollection documentation and exmaples
This commit is contained in:
parent
9f59c34ce6
commit
df4f8b77fb
|
@ -9,6 +9,51 @@ import (
|
|||
"go.starlark.net/syntax"
|
||||
)
|
||||
|
||||
// ResourceCollection stores and instantiates resources for specific provider
|
||||
// and resource.
|
||||
//
|
||||
// outline: types
|
||||
// types:
|
||||
// ResourceCollection
|
||||
// ResourceCollection stores and instantiates resources for specific
|
||||
// provider and resource. The resources can be accessed by indexing or
|
||||
// using the built-in method of `dict`.
|
||||
//
|
||||
// fields:
|
||||
// __provider__ Provider
|
||||
// Provider of this resource collection.
|
||||
// __kind__ string
|
||||
// Kind of the resource collection. Eg.: `data`
|
||||
// __type__ string
|
||||
// Type of the resource collection. Eg.: `aws_instance`
|
||||
//
|
||||
// methods:
|
||||
// __call__(name="", values="") Resource
|
||||
// Returns a new resourced with the given name and values.
|
||||
//
|
||||
// examples:
|
||||
// resource_collection_call.star
|
||||
// Resource instantiation using values, dicts or kwargs.
|
||||
//
|
||||
// params:
|
||||
// name string
|
||||
// Local name of the resource, if `None` is provided it's
|
||||
// autogenerated.
|
||||
// values dict
|
||||
// List of arguments and nested blocks to be set in the new
|
||||
// resource, this values can be also defined using `kwargs`.
|
||||
// search(key="id", value) list
|
||||
// Return all the Resources with the given value in the given key.
|
||||
//
|
||||
// examples:
|
||||
// resource_collection_search.star
|
||||
//
|
||||
// params:
|
||||
// name string
|
||||
// Key to search. The default value is `id`.
|
||||
// value <any>
|
||||
// Value to match in the given key.
|
||||
//
|
||||
type ResourceCollection struct {
|
||||
typ string
|
||||
kind Kind
|
||||
|
@ -201,8 +246,18 @@ func (c *ResourceCollection) Attr(name string) (starlark.Value, error) {
|
|||
switch name {
|
||||
case "search":
|
||||
return starlark.NewBuiltin("search", c.search), nil
|
||||
case "__dict__":
|
||||
return c.toDict(), nil
|
||||
case "__provider__":
|
||||
if c.kind.IsProviderRelated() {
|
||||
if c.provider == nil {
|
||||
return starlark.None, nil
|
||||
}
|
||||
|
||||
return c.provider, nil
|
||||
}
|
||||
case "__kind__":
|
||||
return starlark.String(c.kind), nil
|
||||
case "__type__":
|
||||
return starlark.String(c.typ), nil
|
||||
}
|
||||
|
||||
return c.List.Attr(name)
|
||||
|
@ -210,7 +265,8 @@ func (c *ResourceCollection) Attr(name string) (starlark.Value, error) {
|
|||
|
||||
// AttrNames honors the starlark.HasAttrs interface.
|
||||
func (c *ResourceCollection) AttrNames() []string {
|
||||
return append(c.List.AttrNames(), "search", "__dict__")
|
||||
return append(c.List.AttrNames(),
|
||||
"search", "__provider__", "__kind__", "__type__")
|
||||
}
|
||||
|
||||
func (c *ResourceCollection) search(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, _ []starlark.Tuple) (starlark.Value, error) {
|
||||
|
|
|
@ -13,43 +13,6 @@ import (
|
|||
"go.starlark.net/syntax"
|
||||
)
|
||||
|
||||
func BuiltinProvider(pm *terraform.PluginManager) starlark.Value {
|
||||
return starlark.NewBuiltin("provider", func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
|
||||
var typ, version, name starlark.String
|
||||
switch len(args) {
|
||||
case 3:
|
||||
var ok bool
|
||||
name, ok = args.Index(2).(starlark.String)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected string, got %s", args.Index(2).Type())
|
||||
}
|
||||
fallthrough
|
||||
case 2:
|
||||
var ok bool
|
||||
version, ok = args.Index(1).(starlark.String)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected string, got %s", args.Index(1).Type())
|
||||
}
|
||||
fallthrough
|
||||
case 1:
|
||||
var ok bool
|
||||
typ, ok = args.Index(0).(starlark.String)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected string, got %s", args.Index(0).Type())
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected positional arguments count")
|
||||
}
|
||||
|
||||
p, err := NewProvider(pm, typ.GoString(), version.GoString(), name.GoString())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, p.loadKeywordArgs(kwargs)
|
||||
})
|
||||
}
|
||||
|
||||
// Provider represents a provider as a starlark.Value.
|
||||
//
|
||||
// outline: types
|
||||
|
@ -181,6 +144,26 @@ func (x *Provider) CompareSameType(op syntax.Token, y_ starlark.Value, depth int
|
|||
}
|
||||
}
|
||||
|
||||
// ResourceCollectionGroup represents a group by kind (resource or data resource)
|
||||
// of ResourceCollections for a given provider.
|
||||
//
|
||||
// outline: types
|
||||
// types:
|
||||
// ResourceCollectionGroup
|
||||
// ResourceCollectionGroup represents a group by kind (resource or data
|
||||
// resource) of ResourceCollections for a given provider.
|
||||
//
|
||||
// fields:
|
||||
// __provider__ Provider
|
||||
// Provider of this group.
|
||||
// __kind__ string
|
||||
// Kind of the resources (`data` or `resource`).
|
||||
// <resource-name> ResourceCollection
|
||||
// It returns a ResourceCollection if the resource name is valid for
|
||||
// the schema of the provider. The resource name should be provided
|
||||
// without the provider prefix, `aws_instance` becomes
|
||||
// just `instance`.
|
||||
//
|
||||
type ResourceCollectionGroup struct {
|
||||
provider *Provider
|
||||
kind Kind
|
||||
|
@ -191,11 +174,13 @@ type ResourceCollectionGroup struct {
|
|||
var _ starlark.Value = &ResourceCollectionGroup{}
|
||||
var _ starlark.HasAttrs = &ResourceCollectionGroup{}
|
||||
|
||||
func NewResourceCollectionGroup(p *Provider, k Kind, schemas map[string]providers.Schema) *ResourceCollectionGroup {
|
||||
// NewResourceCollectionGroup returns a new ResourceCollectionGroup for a given
|
||||
// provider and kind based on the given schema.
|
||||
func NewResourceCollectionGroup(p *Provider, k Kind, schema map[string]providers.Schema) *ResourceCollectionGroup {
|
||||
return &ResourceCollectionGroup{
|
||||
provider: p,
|
||||
kind: k,
|
||||
schemas: schemas,
|
||||
schemas: schema,
|
||||
collections: make(map[string]*ResourceCollection),
|
||||
}
|
||||
}
|
||||
|
@ -228,8 +213,14 @@ func (g *ResourceCollectionGroup) Hash() (uint32, error) {
|
|||
|
||||
// Attr honors the starlark.HasAttrs interface.
|
||||
func (g *ResourceCollectionGroup) Attr(name string) (starlark.Value, error) {
|
||||
name = g.provider.typ + "_" + name
|
||||
switch name {
|
||||
case "__provider__":
|
||||
return g.provider, nil
|
||||
case "__kind__":
|
||||
return starlark.String(g.kind), nil
|
||||
}
|
||||
|
||||
name = g.provider.typ + "_" + name
|
||||
if c, ok := g.collections[name]; ok {
|
||||
return c, nil
|
||||
}
|
||||
|
@ -253,5 +244,5 @@ func (g *ResourceCollectionGroup) AttrNames() []string {
|
|||
i++
|
||||
}
|
||||
|
||||
return names
|
||||
return append(names, "__kind__", "__provider__")
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ provider.region = "us-central1"
|
|||
print_provider_info(provider)
|
||||
# Output:
|
||||
# Provider google[id_1] (3.13.0)
|
||||
# Defines Data Sources: 58
|
||||
# Defines Resources: 261
|
||||
# Defines Data Sources: 60
|
||||
# Defines Resources: 263
|
||||
# Configuration: {"project": "acme-app", "region": "us-central1"}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
aws = tf.provider("aws")
|
||||
|
||||
# Resources can be defined in different ways...
|
||||
|
||||
# you can set the resource attributes...
|
||||
v = aws.resource.instance()
|
||||
v.instance_type = "t2.micro"
|
||||
v.tags = {"name": "HelloWorld"}
|
||||
|
||||
# or using a dict in the constructor...
|
||||
d = aws.resource.instance({
|
||||
"instance_type": "t2.micro",
|
||||
"tags": {"name": "HelloWorld"},
|
||||
})
|
||||
|
||||
# or even using kwargs
|
||||
k = aws.resource.instance(instance_type="t2.micro", tags={"name": "HelloWorld"})
|
||||
|
||||
# and all the resources are equivalent:
|
||||
print(v.__dict__)
|
||||
print(d.__dict__)
|
||||
print(k.__dict__)
|
||||
|
||||
# Output:
|
||||
# {"instance_type": "t2.micro", "tags": {"name": "HelloWorld"}}
|
||||
# {"instance_type": "t2.micro", "tags": {"name": "HelloWorld"}}
|
||||
# {"instance_type": "t2.micro", "tags": {"name": "HelloWorld"}}
|
|
@ -0,0 +1,14 @@
|
|||
aws = tf.provider("aws")
|
||||
aws.resource.instance("foo", instance_type="t2.micro")
|
||||
aws.resource.instance("bar", instance_type="a1.medium")
|
||||
aws.resource.instance("qux", instance_type="t2.micro")
|
||||
|
||||
r = aws.resource.instance.search("bar")
|
||||
print("Instance type of `bar`: %s" % r[0].instance_type)
|
||||
|
||||
r = aws.resource.instance.search("instance_type", "t2.micro")
|
||||
print("Instances with 't2.micro`: %d" % len(r))
|
||||
|
||||
# Output:
|
||||
# Instance type of `bar`: a1.medium
|
||||
# Instances with 't2.micro`: 2
|
|
@ -15,8 +15,8 @@ assert.eq("data" in dir(p), True)
|
|||
assert.eq("resource" in dir(p), True)
|
||||
|
||||
# attr
|
||||
assert.eq(len(dir(p.data)), 131)
|
||||
assert.eq(len(dir(p.resource)), 506)
|
||||
assert.eq(len(dir(p.data)), 133)
|
||||
assert.eq(len(dir(p.resource)), 508)
|
||||
|
||||
resources = dir(p.resource)
|
||||
assert.contains(resources, "instance")
|
||||
|
@ -48,6 +48,12 @@ assert.eq(alias.__version__, "2.13.0")
|
|||
kwargs = tf.provider("aws", region="foo")
|
||||
assert.eq(kwargs.region, "foo")
|
||||
|
||||
# ResourceCollectionGroup
|
||||
assert.eq("__kind__" in dir(p.resource), True)
|
||||
assert.eq(p.resource.__kind__, "resource")
|
||||
assert.eq("__provider__" in dir(p.resource), True)
|
||||
assert.eq(p.resource.__provider__, p)
|
||||
|
||||
# compare
|
||||
assert.ne(p, kwargs)
|
||||
assert.ne(p, kwargs)
|
||||
|
|
|
@ -2,6 +2,8 @@ load("assert.star", "assert")
|
|||
|
||||
ignition = tf.provider("ignition", "1.1.0")
|
||||
|
||||
|
||||
|
||||
# attr
|
||||
qux = ignition.data.user()
|
||||
qux.uid = 42
|
||||
|
@ -73,6 +75,10 @@ group.mixed_instances_policy = {
|
|||
assert.eq(group.mixed_instances_policy.launch_template.launch_template_specification.launch_template_id, "bar")
|
||||
|
||||
# attr collections
|
||||
assert.eq("__provider__" in dir(web.network_interface), True)
|
||||
assert.eq("__type__" in dir(web.network_interface), True)
|
||||
assert.eq("__kind__" in dir(web.network_interface), True)
|
||||
|
||||
web.network_interface = [
|
||||
{"network_interface_id": "foo"},
|
||||
{"network_interface_id": "bar"},
|
||||
|
@ -217,18 +223,37 @@ assert.eq(web.__provider__, aws)
|
|||
assert.eq(baz.__provider__, ignition)
|
||||
assert.eq(instanceA.__provider__, aws)
|
||||
assert.eq(home.__provider__, ignition)
|
||||
assert.eq(aws.resource.instance.__provider__, aws)
|
||||
|
||||
# __kind__
|
||||
assert.eq(ignition.data.user().__kind__, "data")
|
||||
assert.eq(aws.resource.instance.__kind__, "resource")
|
||||
assert.eq(aws.resource.instance().__kind__, "resource")
|
||||
assert.eq(aws.resource.autoscaling_group().mixed_instances_policy.__kind__, "nested")
|
||||
assert.eq(web.network_interface.__kind__, "nested")
|
||||
|
||||
# __type__
|
||||
assert.eq(ignition.data.user().__type__, "ignition_user")
|
||||
assert.eq(aws.resource.instance.__type__, "aws_instance")
|
||||
assert.eq(aws.resource.instance().__type__, "aws_instance")
|
||||
assert.eq(aws.resource.autoscaling_group().mixed_instances_policy.__type__, "mixed_instances_policy")
|
||||
assert.eq(web.network_interface.__type__, "network_interface")
|
||||
|
||||
# __name__
|
||||
assert.eq(ignition.data.user().__name__, "id_30")
|
||||
assert.eq(aws.resource.instance().__name__, "id_31")
|
||||
assert.eq(ignition.data.user("given").__name__, "given")
|
||||
|
||||
# __call__
|
||||
assert.eq(ignition.data.user().__name__, "id_32")
|
||||
assert.eq(ignition.data.user("foo").__name__, "foo")
|
||||
assert.eq(ignition.data.user(uid=42).uid, 42)
|
||||
assert.eq(ignition.data.user({"uid": 42}).uid, 42)
|
||||
|
||||
foo = ignition.data.user("foo", {"uid": 42})
|
||||
assert.eq(foo.__name__, "foo")
|
||||
assert.eq(foo.uid, 42)
|
||||
|
||||
foo = ignition.data.user("foo", uid=42)
|
||||
assert.eq(foo.__name__, "foo")
|
||||
assert.eq(foo.uid, 42)
|
Loading…
Reference in New Issue