From 3d4937b7840e157f5b0134f6cdd1bb1b9370de7b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 21 Sep 2016 14:43:18 -0700 Subject: [PATCH] terraform: FlatConfigTransformer --- .../transform-flat-config-basic/child/main.tf | 1 + .../transform-flat-config-basic/main.tf | 6 ++ terraform/transform_config_flat.go | 72 +++++++++++++++++++ terraform/transform_config_flat_test.go | 40 +++++++++++ 4 files changed, 119 insertions(+) create mode 100644 terraform/test-fixtures/transform-flat-config-basic/child/main.tf create mode 100644 terraform/test-fixtures/transform-flat-config-basic/main.tf create mode 100644 terraform/transform_config_flat.go create mode 100644 terraform/transform_config_flat_test.go diff --git a/terraform/test-fixtures/transform-flat-config-basic/child/main.tf b/terraform/test-fixtures/transform-flat-config-basic/child/main.tf new file mode 100644 index 000000000..0c70b1b5d --- /dev/null +++ b/terraform/test-fixtures/transform-flat-config-basic/child/main.tf @@ -0,0 +1 @@ +resource "aws_instance" "baz" {} diff --git a/terraform/test-fixtures/transform-flat-config-basic/main.tf b/terraform/test-fixtures/transform-flat-config-basic/main.tf new file mode 100644 index 000000000..c588350d4 --- /dev/null +++ b/terraform/test-fixtures/transform-flat-config-basic/main.tf @@ -0,0 +1,6 @@ +resource "aws_instance" "foo" {} +resource "aws_instance" "bar" { value = "${aws_instance.foo.value}" } + +module "child" { + source = "./child" +} diff --git a/terraform/transform_config_flat.go b/terraform/transform_config_flat.go new file mode 100644 index 000000000..9d13130d6 --- /dev/null +++ b/terraform/transform_config_flat.go @@ -0,0 +1,72 @@ +package terraform + +import ( + "errors" + + "github.com/hashicorp/terraform/config/module" + "github.com/hashicorp/terraform/dag" +) + +// FlatConfigTransformer is a GraphTransformer that adds the configuration +// to the graph. The module used to configure this transformer must be +// the root module. +// +// In relation to ConfigTransformer: this is a newer generation config +// transformer. It puts the _entire_ config into the graph (there is no +// "flattening" step as before). +type FlatConfigTransformer struct { + Concrete ConcreteResourceNodeFunc // What to turn resources into + + Module *module.Tree +} + +func (t *FlatConfigTransformer) Transform(g *Graph) error { + // If no module, we do nothing + if t.Module == nil { + return nil + } + + // If the module is not loaded, that is an error + if !t.Module.Loaded() { + return errors.New("module must be loaded") + } + + return t.transform(g, t.Module) +} + +func (t *FlatConfigTransformer) transform(g *Graph, m *module.Tree) error { + // If no module, no problem + if m == nil { + return nil + } + + // Transform all the children. + for _, c := range m.Children() { + if err := t.transform(g, c); err != nil { + return err + } + } + + // Get the configuration for this module + config := m.Config() + + // Write all the resources out + for _, r := range config.Resources { + // Grab the address for this resource + addr, err := parseResourceAddressConfig(r) + if err != nil { + return err + } + addr.Path = m.Path() + + abstract := &NodeAbstractResource{Addr: addr} + var node dag.Vertex = abstract + if f := t.Concrete; f != nil { + node = f(abstract) + } + + g.Add(node) + } + + return nil +} diff --git a/terraform/transform_config_flat_test.go b/terraform/transform_config_flat_test.go new file mode 100644 index 000000000..aa393d5a9 --- /dev/null +++ b/terraform/transform_config_flat_test.go @@ -0,0 +1,40 @@ +package terraform + +import ( + "strings" + "testing" +) + +func TestFlatConfigTransformer_nilModule(t *testing.T) { + g := Graph{Path: RootModulePath} + tf := &FlatConfigTransformer{} + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + if len(g.Vertices()) > 0 { + t.Fatal("graph should be empty") + } +} + +func TestFlatConfigTransformer(t *testing.T) { + g := Graph{Path: RootModulePath} + tf := &FlatConfigTransformer{ + Module: testModule(t, "transform-flat-config-basic"), + } + if err := tf.Transform(&g); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(g.String()) + expected := strings.TrimSpace(testTransformFlatConfigBasicStr) + if actual != expected { + t.Fatalf("bad:\n\n%s", actual) + } +} + +const testTransformFlatConfigBasicStr = ` +aws_instance.bar +aws_instance.foo +module.child.aws_instance.baz +`