config: depgraph can contain provider configuratoins
This commit is contained in:
parent
e2fa7094bd
commit
3ccfd4d08c
|
@ -118,6 +118,7 @@ func (r *Resource) ReplaceVariables(vs map[string]string) *Resource {
|
||||||
// ResourceGraph returns a dependency graph of the resources from this
|
// ResourceGraph returns a dependency graph of the resources from this
|
||||||
// Terraform configuration.
|
// Terraform configuration.
|
||||||
func (c *Config) ResourceGraph() *depgraph.Graph {
|
func (c *Config) ResourceGraph() *depgraph.Graph {
|
||||||
|
// This tracks all the resource nouns
|
||||||
nouns := make(map[string]*depgraph.Noun)
|
nouns := make(map[string]*depgraph.Noun)
|
||||||
for _, r := range c.Resources {
|
for _, r := range c.Resources {
|
||||||
noun := &depgraph.Noun{
|
noun := &depgraph.Noun{
|
||||||
|
@ -127,9 +128,30 @@ func (c *Config) ResourceGraph() *depgraph.Graph {
|
||||||
nouns[noun.Name] = noun
|
nouns[noun.Name] = noun
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, noun := range nouns {
|
// Build the list of nouns that we iterate over
|
||||||
r := noun.Meta.(*Resource)
|
nounsList := make([]*depgraph.Noun, 0, len(nouns))
|
||||||
for _, v := range r.Variables {
|
for _, n := range nouns {
|
||||||
|
nounsList = append(nounsList, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This tracks the provider configs that are nouns in our dep graph
|
||||||
|
pcNouns := make(map[string]*depgraph.Noun)
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < len(nounsList) {
|
||||||
|
noun := nounsList[i]
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
// Determine depenencies based on variables. Both resources
|
||||||
|
// and provider configurations have dependencies in this case.
|
||||||
|
var vars map[string]InterpolatedVariable
|
||||||
|
switch n := noun.Meta.(type) {
|
||||||
|
case *Resource:
|
||||||
|
vars = n.Variables
|
||||||
|
case *ProviderConfig:
|
||||||
|
vars = n.Variables
|
||||||
|
}
|
||||||
|
for _, v := range vars {
|
||||||
// Only resource variables impose dependencies
|
// Only resource variables impose dependencies
|
||||||
rv, ok := v.(*ResourceVariable)
|
rv, ok := v.(*ResourceVariable)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -145,12 +167,32 @@ func (c *Config) ResourceGraph() *depgraph.Graph {
|
||||||
|
|
||||||
noun.Deps = append(noun.Deps, dep)
|
noun.Deps = append(noun.Deps, dep)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create the list of nouns that the depgraph.Graph struct expects
|
// If this is a Resource, then check if we have to also
|
||||||
nounsList := make([]*depgraph.Noun, 0, len(nouns))
|
// depend on a provider configuration.
|
||||||
for _, n := range nouns {
|
if r, ok := noun.Meta.(*Resource); ok {
|
||||||
nounsList = append(nounsList, n)
|
// If there is a provider config that matches this resource
|
||||||
|
// then we add that as a dependency.
|
||||||
|
if pcName := r.ProviderConfigName(c.ProviderConfigs); pcName != "" {
|
||||||
|
pcNoun, ok := pcNouns[pcName]
|
||||||
|
if !ok {
|
||||||
|
pcNoun = &depgraph.Noun{
|
||||||
|
Name: fmt.Sprintf("provider.%s", pcName),
|
||||||
|
Meta: c.ProviderConfigs[pcName],
|
||||||
|
}
|
||||||
|
pcNouns[pcName] = pcNoun
|
||||||
|
nounsList = append(nounsList, pcNoun)
|
||||||
|
}
|
||||||
|
|
||||||
|
dep := &depgraph.Dependency{
|
||||||
|
Name: pcName,
|
||||||
|
Source: noun,
|
||||||
|
Target: pcNoun,
|
||||||
|
}
|
||||||
|
|
||||||
|
noun.Deps = append(noun.Deps, dep)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a root that just depends on everything else finishing.
|
// Create a root that just depends on everything else finishing.
|
||||||
|
@ -170,6 +212,14 @@ func (c *Config) ResourceGraph() *depgraph.Graph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate does some basic semantic checking of the configuration.
|
||||||
|
func (c *Config) Validate() error {
|
||||||
|
// TODO(mitchellh): make sure all referenced variables exist
|
||||||
|
// TODO(mitchellh): make sure types/names have valid values (characters)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Required tests whether a variable is required or not.
|
// Required tests whether a variable is required or not.
|
||||||
func (v *Variable) Required() bool {
|
func (v *Variable) Required() bool {
|
||||||
return !v.defaultSet
|
return !v.defaultSet
|
||||||
|
|
|
@ -128,16 +128,21 @@ func TestResourceReplaceVariables(t *testing.T) {
|
||||||
|
|
||||||
const resourceGraphValue = `
|
const resourceGraphValue = `
|
||||||
root: root
|
root: root
|
||||||
root -> aws_security_group.firewall
|
openstack_floating_ip.random
|
||||||
root -> aws_instance.web
|
|
||||||
root -> aws_load_balancer.weblb
|
|
||||||
aws_security_group.firewall
|
aws_security_group.firewall
|
||||||
|
aws_security_group.firewall -> provider.aws
|
||||||
aws_instance.web
|
aws_instance.web
|
||||||
aws_instance.web -> aws_security_group.firewall
|
aws_instance.web -> aws_security_group.firewall
|
||||||
|
aws_instance.web -> provider.aws
|
||||||
aws_load_balancer.weblb
|
aws_load_balancer.weblb
|
||||||
aws_load_balancer.weblb -> aws_instance.web
|
aws_load_balancer.weblb -> aws_instance.web
|
||||||
|
aws_load_balancer.weblb -> provider.aws
|
||||||
|
provider.aws
|
||||||
|
provider.aws -> openstack_floating_ip.random
|
||||||
root
|
root
|
||||||
|
root -> openstack_floating_ip.random
|
||||||
root -> aws_security_group.firewall
|
root -> aws_security_group.firewall
|
||||||
root -> aws_instance.web
|
root -> aws_instance.web
|
||||||
root -> aws_load_balancer.weblb
|
root -> aws_load_balancer.weblb
|
||||||
|
root -> provider.aws
|
||||||
`
|
`
|
||||||
|
|
|
@ -3,6 +3,12 @@ variable "foo" {
|
||||||
description = "bar";
|
description = "bar";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
foo = "${openstack_floating_ip.random.value}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "openstack_floating_ip" "random" {}
|
||||||
|
|
||||||
resource "aws_security_group" "firewall" {}
|
resource "aws_security_group" "firewall" {}
|
||||||
|
|
||||||
resource "aws_instance" "web" {
|
resource "aws_instance" "web" {
|
||||||
|
|
|
@ -114,13 +114,6 @@ func (g *Graph) String() string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
buf.WriteString(fmt.Sprintf("root: %s\n", g.Root.Name))
|
buf.WriteString(fmt.Sprintf("root: %s\n", g.Root.Name))
|
||||||
for _, dep := range g.Root.Deps {
|
|
||||||
buf.WriteString(fmt.Sprintf(
|
|
||||||
" %s -> %s\n",
|
|
||||||
dep.Source,
|
|
||||||
dep.Target))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, n := range g.Nouns {
|
for _, n := range g.Nouns {
|
||||||
buf.WriteString(fmt.Sprintf("%s\n", n.Name))
|
buf.WriteString(fmt.Sprintf("%s\n", n.Name))
|
||||||
for _, dep := range n.Deps {
|
for _, dep := range n.Deps {
|
||||||
|
|
Loading…
Reference in New Issue