config: allow atlas block

This commit is contained in:
Mitchell Hashimoto 2015-03-05 12:56:31 -08:00
parent ca8e2085f3
commit fdded8ca14
9 changed files with 81 additions and 0 deletions

View File

@ -21,6 +21,7 @@ func Append(c1, c2 *Config) (*Config, error) {
c.unknownKeys = append(c.unknownKeys, k) c.unknownKeys = append(c.unknownKeys, k)
} }
} }
for _, k := range c2.unknownKeys { for _, k := range c2.unknownKeys {
_, present := unknowns[k] _, present := unknowns[k]
if !present { if !present {
@ -29,6 +30,11 @@ func Append(c1, c2 *Config) (*Config, error) {
} }
} }
c.Atlas = c1.Atlas
if c2.Atlas != nil {
c.Atlas = c2.Atlas
}
if len(c1.Modules) > 0 || len(c2.Modules) > 0 { if len(c1.Modules) > 0 || len(c2.Modules) > 0 {
c.Modules = make( c.Modules = make(
[]*Module, 0, len(c1.Modules)+len(c2.Modules)) []*Module, 0, len(c1.Modules)+len(c2.Modules))

View File

@ -12,6 +12,9 @@ func TestAppend(t *testing.T) {
}{ }{
{ {
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "foo",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "foo"}, &Module{Name: "foo"},
}, },
@ -32,6 +35,9 @@ func TestAppend(t *testing.T) {
}, },
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "bar",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "bar"}, &Module{Name: "bar"},
}, },
@ -52,6 +58,9 @@ func TestAppend(t *testing.T) {
}, },
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "bar",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "foo"}, &Module{Name: "foo"},
&Module{Name: "bar"}, &Module{Name: "bar"},

View File

@ -28,6 +28,7 @@ type Config struct {
// any meaningful directory. // any meaningful directory.
Dir string Dir string
Atlas *AtlasConfig
Modules []*Module Modules []*Module
ProviderConfigs []*ProviderConfig ProviderConfigs []*ProviderConfig
Resources []*Resource Resources []*Resource
@ -39,6 +40,13 @@ type Config struct {
unknownKeys []string unknownKeys []string
} }
// AtlasConfig is the configuration for building in HashiCorp's Atlas.
type AtlasConfig struct {
Name string
Include []string
Exclude []string
}
// Module is a module used within a configuration. // Module is a module used within a configuration.
// //
// This does not represent a module itself, this represents a module // This does not represent a module itself, this represents a module

View File

@ -17,6 +17,7 @@ type hclConfigurable struct {
func (t *hclConfigurable) Config() (*Config, error) { func (t *hclConfigurable) Config() (*Config, error) {
validKeys := map[string]struct{}{ validKeys := map[string]struct{}{
"atlas": struct{}{},
"module": struct{}{}, "module": struct{}{},
"output": struct{}{}, "output": struct{}{},
"provider": struct{}{}, "provider": struct{}{},
@ -70,6 +71,15 @@ func (t *hclConfigurable) Config() (*Config, error) {
} }
} }
// Get Atlas configuration
if atlas := t.Object.Get("atlas", false); atlas != nil {
var err error
config.Atlas, err = loadAtlasHcl(atlas)
if err != nil {
return nil, err
}
}
// Build the modules // Build the modules
if modules := t.Object.Get("module", false); modules != nil { if modules := t.Object.Get("module", false); modules != nil {
var err error var err error
@ -187,6 +197,19 @@ func loadFileHcl(root string) (configurable, []string, error) {
return result, nil, nil return result, nil, nil
} }
// Given a handle to a HCL object, this transforms it into the Atlas
// configuration.
func loadAtlasHcl(obj *hclobj.Object) (*AtlasConfig, error) {
var config AtlasConfig
if err := hcl.DecodeObject(&config, obj); err != nil {
return nil, fmt.Errorf(
"Error reading atlas config: %s",
err)
}
return &config, nil
}
// Given a handle to a HCL object, this recurses into the structure // Given a handle to a HCL object, this recurses into the structure
// and pulls out a list of modules. // and pulls out a list of modules.
// //

View File

@ -2,6 +2,7 @@ package config
import ( import (
"path/filepath" "path/filepath"
"reflect"
"strings" "strings"
"testing" "testing"
) )
@ -57,6 +58,11 @@ func TestLoadBasic(t *testing.T) {
t.Fatalf("bad: %#v", c.Dir) t.Fatalf("bad: %#v", c.Dir)
} }
expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
t.Fatalf("bad: %#v", c.Atlas)
}
actual := variablesStr(c.Variables) actual := variablesStr(c.Variables)
if actual != strings.TrimSpace(basicVariablesStr) { if actual != strings.TrimSpace(basicVariablesStr) {
t.Fatalf("bad:\n%s", actual) t.Fatalf("bad:\n%s", actual)
@ -132,6 +138,11 @@ func TestLoadBasic_json(t *testing.T) {
t.Fatalf("bad: %#v", c.Dir) t.Fatalf("bad: %#v", c.Dir)
} }
expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"}
if !reflect.DeepEqual(c.Atlas, expectedAtlas) {
t.Fatalf("bad: %#v", c.Atlas)
}
actual := variablesStr(c.Variables) actual := variablesStr(c.Variables)
if actual != strings.TrimSpace(basicVariablesStr) { if actual != strings.TrimSpace(basicVariablesStr) {
t.Fatalf("bad:\n%s", actual) t.Fatalf("bad:\n%s", actual)

View File

@ -25,6 +25,13 @@ func Merge(c1, c2 *Config) (*Config, error) {
} }
} }
// Merge Atlas configuration. This is a dumb one overrides the other
// sort of merge.
c.Atlas = c1.Atlas
if c2.Atlas != nil {
c.Atlas = c2.Atlas
}
// NOTE: Everything below is pretty gross. Due to the lack of generics // NOTE: Everything below is pretty gross. Due to the lack of generics
// in Go, there is some hoop-jumping involved to make this merging a // in Go, there is some hoop-jumping involved to make this merging a
// little more test-friendly and less repetitive. Ironically, making it // little more test-friendly and less repetitive. Ironically, making it

View File

@ -13,6 +13,9 @@ func TestMerge(t *testing.T) {
// Normal good case. // Normal good case.
{ {
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "foo",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "foo"}, &Module{Name: "foo"},
}, },
@ -33,6 +36,9 @@ func TestMerge(t *testing.T) {
}, },
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "bar",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "bar"}, &Module{Name: "bar"},
}, },
@ -53,6 +59,9 @@ func TestMerge(t *testing.T) {
}, },
&Config{ &Config{
Atlas: &AtlasConfig{
Name: "bar",
},
Modules: []*Module{ Modules: []*Module{
&Module{Name: "foo"}, &Module{Name: "foo"},
&Module{Name: "bar"}, &Module{Name: "bar"},

View File

@ -49,3 +49,7 @@ resource "aws_instance" "db" {
output "web_ip" { output "web_ip" {
value = "${aws_instance.web.private_ip}" value = "${aws_instance.web.private_ip}"
} }
atlas {
name = "mitchellh/foo"
}

View File

@ -63,5 +63,9 @@
"web_ip": { "web_ip": {
"value": "${aws_instance.web.private_ip}" "value": "${aws_instance.web.private_ip}"
} }
},
"atlas": {
"name": "mitchellh/foo"
} }
} }