From 7bd7e4218f967cb61e65d500f374f5f8889e1255 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 19 Jul 2014 16:05:48 -0700 Subject: [PATCH] config: make ProviderConfigs slice --- config/config.go | 8 +++++--- config/config_test.go | 10 +++++----- config/loader_libucl.go | 13 +++++++++---- config/loader_test.go | 10 ++++++---- config/merge.go | 19 +++++++++++++------ terraform/graph.go | 13 +++++++++++-- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/config/config.go b/config/config.go index 7ea4d5632..442035492 100644 --- a/config/config.go +++ b/config/config.go @@ -13,7 +13,7 @@ import ( // Config is the configuration that comes from loading a collection // of Terraform templates. type Config struct { - ProviderConfigs map[string]*ProviderConfig + ProviderConfigs []*ProviderConfig Resources []*Resource Variables []*Variable Outputs []*Output @@ -28,6 +28,7 @@ type Config struct { // For example, Terraform needs to set the AWS access keys for the AWS // resource provider. type ProviderConfig struct { + Name string RawConfig *RawConfig } @@ -99,9 +100,10 @@ type UserVariable struct { // ProviderConfigName returns the name of the provider configuration in // the given mapping that maps to the proper provider configuration // for this resource. -func ProviderConfigName(t string, pcs map[string]*ProviderConfig) string { +func ProviderConfigName(t string, pcs []*ProviderConfig) string { lk := "" - for k, _ := range pcs { + for _, v := range pcs { + k := v.Name if strings.HasPrefix(t, k) && len(k) > len(lk) { lk = k } diff --git a/config/config_test.go b/config/config_test.go index 1a5ecb8d9..4c66466b1 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -151,11 +151,11 @@ func TestNewUserVariable(t *testing.T) { } func TestProviderConfigName(t *testing.T) { - pcs := map[string]*ProviderConfig{ - "aw": new(ProviderConfig), - "aws": new(ProviderConfig), - "a": new(ProviderConfig), - "gce_": new(ProviderConfig), + pcs := []*ProviderConfig{ + &ProviderConfig{Name: "aw"}, + &ProviderConfig{Name: "aws"}, + &ProviderConfig{Name: "a"}, + &ProviderConfig{Name: "gce_"}, } n := ProviderConfigName("aws_instance", pcs) diff --git a/config/loader_libucl.go b/config/loader_libucl.go index 81f9f5068..c6050d922 100644 --- a/config/loader_libucl.go +++ b/config/loader_libucl.go @@ -234,7 +234,7 @@ func loadOutputsLibucl(o *libucl.Object) ([]*Output, error) { // LoadProvidersLibucl recurses into the given libucl object and turns // it into a mapping of provider configs. -func loadProvidersLibucl(o *libucl.Object) (map[string]*ProviderConfig, error) { +func loadProvidersLibucl(o *libucl.Object) ([]*ProviderConfig, error) { objects := make(map[string]*libucl.Object) // Iterate over all the "provider" blocks and get the keys along with @@ -252,8 +252,12 @@ func loadProvidersLibucl(o *libucl.Object) (map[string]*ProviderConfig, error) { } iter.Close() + if len(objects) == 0 { + return nil, nil + } + // Go through each object and turn it into an actual result. - result := make(map[string]*ProviderConfig) + result := make([]*ProviderConfig, 0, len(objects)) for n, o := range objects { var config map[string]interface{} @@ -269,9 +273,10 @@ func loadProvidersLibucl(o *libucl.Object) (map[string]*ProviderConfig, error) { err) } - result[n] = &ProviderConfig{ + result = append(result, &ProviderConfig{ + Name: n, RawConfig: rawConfig, - } + }) } return result, nil diff --git a/config/loader_test.go b/config/loader_test.go index 2266ee401..11ca7f457 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -248,17 +248,19 @@ func TestLoad_connections(t *testing.T) { // This helper turns a provider configs field into a deterministic // string value for comparison in tests. -func providerConfigsStr(pcs map[string]*ProviderConfig) string { +func providerConfigsStr(pcs []*ProviderConfig) string { result := "" ns := make([]string, 0, len(pcs)) - for n, _ := range pcs { - ns = append(ns, n) + m := make(map[string]*ProviderConfig) + for _, n := range pcs { + ns = append(ns, n.Name) + m[n.Name] = n } sort.Strings(ns) for _, n := range ns { - pc := pcs[n] + pc := m[n] result += fmt.Sprintf("%s\n", n) diff --git a/config/merge.go b/config/merge.go index a1df4dbfa..628f34056 100644 --- a/config/merge.go +++ b/config/merge.go @@ -68,12 +68,19 @@ func Merge(c1, c2 *Config) (*Config, error) { // Merge provider configs: If they collide, we just take the latest one // for now. In the future, we might provide smarter merge functionality. - c.ProviderConfigs = make(map[string]*ProviderConfig) - for k, v := range c1.ProviderConfigs { - c.ProviderConfigs[k] = v - } - for k, v := range c2.ProviderConfigs { - c.ProviderConfigs[k] = v + if len(c1.ProviderConfigs) > 0 || len(c2.ProviderConfigs) > 0 { + m := make(map[string]*ProviderConfig) + for _, v := range c1.ProviderConfigs { + m[v.Name] = v + } + for _, v := range c2.ProviderConfigs { + m[v.Name] = v + } + + c.ProviderConfigs = make([]*ProviderConfig, 0, len(m)) + for _, v := range m { + c.ProviderConfigs = append(c.ProviderConfigs, v) + } } // Merge resources: If they collide, we just take the latest one diff --git a/terraform/graph.go b/terraform/graph.go index e757c3072..3232aaa10 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -462,7 +462,8 @@ func graphAddProviderConfigs(g *depgraph.Graph, c *config.Config) { } // Look up the provider config for this resource - pcName := config.ProviderConfigName(resourceNode.Type, c.ProviderConfigs) + pcName := config.ProviderConfigName( + resourceNode.Type, c.ProviderConfigs) if pcName == "" { continue } @@ -470,11 +471,19 @@ func graphAddProviderConfigs(g *depgraph.Graph, c *config.Config) { // We have one, so build the noun if it hasn't already been made pcNoun, ok := pcNouns[pcName] if !ok { + var pc *config.ProviderConfig + for _, v := range c.ProviderConfigs { + if v.Name == pcName { + pc = v + break + } + } + pcNoun = &depgraph.Noun{ Name: fmt.Sprintf("provider.%s", pcName), Meta: &GraphNodeResourceProvider{ ID: pcName, - Config: c.ProviderConfigs[pcName], + Config: pc, }, } pcNouns[pcName] = pcNoun