mirror of
https://github.com/mcuadros/ascode
synced 2024-11-23 01:11:59 +01:00
starlark/types: Resource.depends_on support
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
This commit is contained in:
parent
5eee1fa944
commit
d25c7b32a2
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl2/hcl"
|
||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
||||
"github.com/hashicorp/hcl2/hclwrite"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"go.starlark.net/starlark"
|
||||
@ -69,12 +70,14 @@ func (r *Resource) ToHCL(b *hclwrite.Body) {
|
||||
body := block.Body()
|
||||
|
||||
if r.parent.kind == ProviderKind {
|
||||
body.SetAttributeTraversal("provider", hcl.Traversal{hcl.TraverseRoot{
|
||||
Name: fmt.Sprintf("%s.%s", r.parent.typ, r.parent.Name()),
|
||||
}})
|
||||
body.SetAttributeTraversal("provider", hcl.Traversal{
|
||||
hcl.TraverseRoot{Name: r.parent.typ},
|
||||
hcl.TraverseAttr{Name: r.parent.Name()},
|
||||
})
|
||||
}
|
||||
|
||||
r.doToHCLAttributes(body)
|
||||
r.doToHCLDependencies(body)
|
||||
}
|
||||
|
||||
func (r *Resource) doToHCLAttributes(body *hclwrite.Body) {
|
||||
@ -84,11 +87,10 @@ func (r *Resource) doToHCLAttributes(body *hclwrite.Body) {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO(mcuadros): I don't know how to do this properly, meanwhile, this works.
|
||||
if c, ok := v.v.(*Computed); ok {
|
||||
body.SetAttributeTraversal(k, hcl.Traversal{hcl.TraverseRoot{
|
||||
Name: c.String(),
|
||||
}})
|
||||
body.SetAttributeTraversal(k, hcl.Traversal{
|
||||
hcl.TraverseRoot{Name: c.String()},
|
||||
})
|
||||
|
||||
continue
|
||||
}
|
||||
@ -107,3 +109,44 @@ func (r *Resource) doToHCLAttributes(body *hclwrite.Body) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Resource) doToHCLDependencies(body *hclwrite.Body) {
|
||||
if len(r.dependenies) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
toks := []*hclwrite.Token{}
|
||||
toks = append(toks, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenIdent,
|
||||
Bytes: []byte("depends_on"),
|
||||
})
|
||||
|
||||
toks = append(toks, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenEqual, Bytes: []byte{'='},
|
||||
}, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenOBrack, Bytes: []byte{'['},
|
||||
})
|
||||
|
||||
l := len(r.dependenies)
|
||||
for i, dep := range r.dependenies {
|
||||
name := fmt.Sprintf("%s.%s", dep.typ, dep.Name())
|
||||
toks = append(toks, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenIdent, Bytes: []byte(name),
|
||||
})
|
||||
|
||||
if i+1 == l {
|
||||
break
|
||||
}
|
||||
|
||||
toks = append(toks, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenComma, Bytes: []byte{','},
|
||||
})
|
||||
}
|
||||
|
||||
toks = append(toks, &hclwrite.Token{
|
||||
Type: hclsyntax.TokenCBrack, Bytes: []byte{']'},
|
||||
})
|
||||
|
||||
body.AppendUnstructuredTokens(toks)
|
||||
body.AppendNewline()
|
||||
}
|
||||
|
@ -37,8 +37,10 @@ type Resource struct {
|
||||
typ string
|
||||
kind Kind
|
||||
block *configschema.Block
|
||||
parent *Resource
|
||||
values map[string]*Value
|
||||
|
||||
parent *Resource
|
||||
dependenies []*Resource
|
||||
}
|
||||
|
||||
// MakeResource returns a new resource of the given kind, type based on the
|
||||
@ -121,6 +123,8 @@ func (r *Resource) Hash() (uint32, error) {
|
||||
// Attr honors the starlark.HasAttrs interface.
|
||||
func (r *Resource) Attr(name string) (starlark.Value, error) {
|
||||
switch name {
|
||||
case "depends_on":
|
||||
return starlark.NewBuiltin("depends_on", r.dependsOn), nil
|
||||
case "__dict__":
|
||||
return r.toDict(), nil
|
||||
}
|
||||
@ -233,6 +237,25 @@ func (r *Resource) toDict() *starlark.Dict {
|
||||
return d
|
||||
}
|
||||
|
||||
func (r *Resource) dependsOn(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, _ []starlark.Tuple) (starlark.Value, error) {
|
||||
resources := make([]*Resource, len(args))
|
||||
for i, arg := range args {
|
||||
resource, ok := arg.(*Resource)
|
||||
if !ok || resource.kind != DataSourceKind && resource.kind != ResourceKind {
|
||||
return nil, fmt.Errorf("expected Resource<[data|resource].*>, got %s", arg.Type())
|
||||
}
|
||||
|
||||
if r == resource {
|
||||
return nil, fmt.Errorf("can't depend on itself")
|
||||
}
|
||||
|
||||
resources[i] = resource
|
||||
}
|
||||
|
||||
r.dependenies = append(r.dependenies, resources...)
|
||||
return starlark.None, nil
|
||||
}
|
||||
|
||||
// CompareSameType honors starlark.Comprable interface.
|
||||
func (x *Resource) CompareSameType(op syntax.Token, y_ starlark.Value, depth int) (bool, error) {
|
||||
y := y_.(*Resource)
|
||||
|
6
starlark/types/testdata/hcl.star
vendored
6
starlark/types/testdata/hcl.star
vendored
@ -9,10 +9,12 @@ ubuntu.filter(name = "name", values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.0
|
||||
ubuntu.filter(name = "virtualization-type", values = ["hvm"])
|
||||
ubuntu.owners = ["099720109477"]
|
||||
|
||||
fedora = aws.data.ami("fedora")
|
||||
web = aws.resource.instance(instance_type = "t2.micro")
|
||||
web.depends_on(ubuntu, fedora)
|
||||
|
||||
#web.instance_type = "t2.micro"
|
||||
#web.ami = ami.id
|
||||
web.instance_type = "t2.micro"
|
||||
web.ami = ubuntu.id
|
||||
|
||||
template = aws.resource.launch_template()
|
||||
template.name_prefix = "example"
|
||||
|
15
starlark/types/testdata/resource.star
vendored
15
starlark/types/testdata/resource.star
vendored
@ -126,3 +126,18 @@ assert.eq(disk.__dict__, {
|
||||
"label": "home"
|
||||
}]
|
||||
})
|
||||
|
||||
|
||||
# depends_on
|
||||
userA = p.data.user()
|
||||
userB = p.data.user()
|
||||
userA.depends_on(userB)
|
||||
|
||||
def dependsOnNonResource(): userA.depends_on(42)
|
||||
assert.fails(dependsOnNonResource, "expected Resource<\\[data|resource\\].\\*>, got int")
|
||||
|
||||
def dependsOnNestedResource(): userA.depends_on(disk.partition())
|
||||
assert.fails(dependsOnNestedResource, "expected Resource<\\[data|resource\\].\\*>, got Resource<nested.partition>")
|
||||
|
||||
def dependsOnItself(): userA.depends_on(userA)
|
||||
assert.fails(dependsOnItself, "can't depend on itself")
|
Loading…
Reference in New Issue
Block a user