config: make ProviderConfigs slice

This commit is contained in:
Mitchell Hashimoto 2014-07-19 16:05:48 -07:00
parent 3834846418
commit 7bd7e4218f
6 changed files with 49 additions and 24 deletions

View File

@ -13,7 +13,7 @@ import (
// Config is the configuration that comes from loading a collection // Config is the configuration that comes from loading a collection
// of Terraform templates. // of Terraform templates.
type Config struct { type Config struct {
ProviderConfigs map[string]*ProviderConfig ProviderConfigs []*ProviderConfig
Resources []*Resource Resources []*Resource
Variables []*Variable Variables []*Variable
Outputs []*Output Outputs []*Output
@ -28,6 +28,7 @@ type Config struct {
// For example, Terraform needs to set the AWS access keys for the AWS // For example, Terraform needs to set the AWS access keys for the AWS
// resource provider. // resource provider.
type ProviderConfig struct { type ProviderConfig struct {
Name string
RawConfig *RawConfig RawConfig *RawConfig
} }
@ -99,9 +100,10 @@ type UserVariable struct {
// ProviderConfigName returns the name of the provider configuration in // ProviderConfigName returns the name of the provider configuration in
// the given mapping that maps to the proper provider configuration // the given mapping that maps to the proper provider configuration
// for this resource. // for this resource.
func ProviderConfigName(t string, pcs map[string]*ProviderConfig) string { func ProviderConfigName(t string, pcs []*ProviderConfig) string {
lk := "" lk := ""
for k, _ := range pcs { for _, v := range pcs {
k := v.Name
if strings.HasPrefix(t, k) && len(k) > len(lk) { if strings.HasPrefix(t, k) && len(k) > len(lk) {
lk = k lk = k
} }

View File

@ -151,11 +151,11 @@ func TestNewUserVariable(t *testing.T) {
} }
func TestProviderConfigName(t *testing.T) { func TestProviderConfigName(t *testing.T) {
pcs := map[string]*ProviderConfig{ pcs := []*ProviderConfig{
"aw": new(ProviderConfig), &ProviderConfig{Name: "aw"},
"aws": new(ProviderConfig), &ProviderConfig{Name: "aws"},
"a": new(ProviderConfig), &ProviderConfig{Name: "a"},
"gce_": new(ProviderConfig), &ProviderConfig{Name: "gce_"},
} }
n := ProviderConfigName("aws_instance", pcs) n := ProviderConfigName("aws_instance", pcs)

View File

@ -234,7 +234,7 @@ func loadOutputsLibucl(o *libucl.Object) ([]*Output, error) {
// LoadProvidersLibucl recurses into the given libucl object and turns // LoadProvidersLibucl recurses into the given libucl object and turns
// it into a mapping of provider configs. // 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) objects := make(map[string]*libucl.Object)
// Iterate over all the "provider" blocks and get the keys along with // 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() iter.Close()
if len(objects) == 0 {
return nil, nil
}
// Go through each object and turn it into an actual result. // 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 { for n, o := range objects {
var config map[string]interface{} var config map[string]interface{}
@ -269,9 +273,10 @@ func loadProvidersLibucl(o *libucl.Object) (map[string]*ProviderConfig, error) {
err) err)
} }
result[n] = &ProviderConfig{ result = append(result, &ProviderConfig{
Name: n,
RawConfig: rawConfig, RawConfig: rawConfig,
} })
} }
return result, nil return result, nil

View File

@ -248,17 +248,19 @@ func TestLoad_connections(t *testing.T) {
// This helper turns a provider configs field into a deterministic // This helper turns a provider configs field into a deterministic
// string value for comparison in tests. // string value for comparison in tests.
func providerConfigsStr(pcs map[string]*ProviderConfig) string { func providerConfigsStr(pcs []*ProviderConfig) string {
result := "" result := ""
ns := make([]string, 0, len(pcs)) ns := make([]string, 0, len(pcs))
for n, _ := range pcs { m := make(map[string]*ProviderConfig)
ns = append(ns, n) for _, n := range pcs {
ns = append(ns, n.Name)
m[n.Name] = n
} }
sort.Strings(ns) sort.Strings(ns)
for _, n := range ns { for _, n := range ns {
pc := pcs[n] pc := m[n]
result += fmt.Sprintf("%s\n", n) result += fmt.Sprintf("%s\n", n)

View File

@ -68,12 +68,19 @@ func Merge(c1, c2 *Config) (*Config, error) {
// Merge provider configs: If they collide, we just take the latest one // Merge provider configs: If they collide, we just take the latest one
// for now. In the future, we might provide smarter merge functionality. // for now. In the future, we might provide smarter merge functionality.
c.ProviderConfigs = make(map[string]*ProviderConfig) if len(c1.ProviderConfigs) > 0 || len(c2.ProviderConfigs) > 0 {
for k, v := range c1.ProviderConfigs { m := make(map[string]*ProviderConfig)
c.ProviderConfigs[k] = v 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)
} }
for k, v := range c2.ProviderConfigs {
c.ProviderConfigs[k] = v
} }
// Merge resources: If they collide, we just take the latest one // Merge resources: If they collide, we just take the latest one

View File

@ -462,7 +462,8 @@ func graphAddProviderConfigs(g *depgraph.Graph, c *config.Config) {
} }
// Look up the provider config for this resource // Look up the provider config for this resource
pcName := config.ProviderConfigName(resourceNode.Type, c.ProviderConfigs) pcName := config.ProviderConfigName(
resourceNode.Type, c.ProviderConfigs)
if pcName == "" { if pcName == "" {
continue 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 // We have one, so build the noun if it hasn't already been made
pcNoun, ok := pcNouns[pcName] pcNoun, ok := pcNouns[pcName]
if !ok { if !ok {
var pc *config.ProviderConfig
for _, v := range c.ProviderConfigs {
if v.Name == pcName {
pc = v
break
}
}
pcNoun = &depgraph.Noun{ pcNoun = &depgraph.Noun{
Name: fmt.Sprintf("provider.%s", pcName), Name: fmt.Sprintf("provider.%s", pcName),
Meta: &GraphNodeResourceProvider{ Meta: &GraphNodeResourceProvider{
ID: pcName, ID: pcName,
Config: c.ProviderConfigs[pcName], Config: pc,
}, },
} }
pcNouns[pcName] = pcNoun pcNouns[pcName] = pcNoun