core: Convert context vars to map[string]interface{}

This is the first step in allowing overrides of map and list variables.
We convert Context.variables to map[string]interface{} from
map[string]string and fix up all the call sites.
This commit is contained in:
James Nugent 2016-07-18 12:52:10 -05:00
parent d4e8616a9c
commit 5d18f41f04
12 changed files with 60 additions and 55 deletions

View File

@ -294,7 +294,7 @@ func (m *Meta) contextOpts() *terraform.ContextOpts {
copy(opts.Hooks[1:], m.ContextOpts.Hooks)
copy(opts.Hooks[len(m.ContextOpts.Hooks)+1:], m.extraHooks)
vs := make(map[string]string)
vs := make(map[string]interface{})
for k, v := range opts.Variables {
vs[k] = v
}

View File

@ -276,21 +276,21 @@ func (c *PushCommand) Synopsis() string {
// pushClient is implementd internally to control where pushes go. This is
// either to Atlas or a mock for testing.
type pushClient interface {
Get(string) (map[string]string, error)
Get(string) (map[string]interface{}, error)
Upsert(*pushUpsertOptions) (int, error)
}
type pushUpsertOptions struct {
Name string
Archive *archive.Archive
Variables map[string]string
Variables map[string]interface{}
}
type atlasPushClient struct {
Client *atlas.Client
}
func (c *atlasPushClient) Get(name string) (map[string]string, error) {
func (c *atlasPushClient) Get(name string) (map[string]interface{}, error) {
user, name, err := atlas.ParseSlug(name)
if err != nil {
return nil, err
@ -301,7 +301,7 @@ func (c *atlasPushClient) Get(name string) (map[string]string, error) {
return nil, err
}
var variables map[string]string
var variables map[string]interface{}
if version != nil {
variables = version.Variables
}
@ -333,7 +333,7 @@ type mockPushClient struct {
GetCalled bool
GetName string
GetResult map[string]string
GetResult map[string]interface{}
GetError error
UpsertCalled bool
@ -342,7 +342,7 @@ type mockPushClient struct {
UpsertError error
}
func (c *mockPushClient) Get(name string) (map[string]string, error) {
func (c *mockPushClient) Get(name string) (map[string]interface{}, error) {
c.GetCalled = true
c.GetName = name
return c.GetResult, c.GetError

View File

@ -61,7 +61,7 @@ func TestPush_good(t *testing.T) {
t.Fatalf("bad: %#v", actual)
}
variables := make(map[string]string)
variables := make(map[string]interface{})
if !reflect.DeepEqual(client.UpsertOptions.Variables, variables) {
t.Fatalf("bad: %#v", client.UpsertOptions)
}
@ -115,7 +115,7 @@ func TestPush_input(t *testing.T) {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
}
variables := map[string]string{
variables := map[string]interface{}{
"foo": "foo",
}
if !reflect.DeepEqual(client.UpsertOptions.Variables, variables) {
@ -143,7 +143,7 @@ func TestPush_inputPartial(t *testing.T) {
client := &mockPushClient{
File: archivePath,
GetResult: map[string]string{"foo": "bar"},
GetResult: map[string]interface{}{"foo": "bar"},
}
ui := new(cli.MockUi)
c := &PushCommand{
@ -170,7 +170,7 @@ func TestPush_inputPartial(t *testing.T) {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
}
variables := map[string]string{
variables := map[string]interface{}{
"foo": "bar",
"bar": "foo",
}
@ -208,7 +208,7 @@ func TestPush_localOverride(t *testing.T) {
client := &mockPushClient{File: archivePath}
// Provided vars should override existing ones
client.GetResult = map[string]string{
client.GetResult = map[string]interface{}{
"foo": "old",
}
ui := new(cli.MockUi)
@ -247,7 +247,7 @@ func TestPush_localOverride(t *testing.T) {
t.Fatalf("bad: %#v", client.UpsertOptions)
}
variables := map[string]string{
variables := map[string]interface{}{
"foo": "bar",
"bar": "foo",
}
@ -285,7 +285,7 @@ func TestPush_preferAtlas(t *testing.T) {
client := &mockPushClient{File: archivePath}
// Provided vars should override existing ones
client.GetResult = map[string]string{
client.GetResult = map[string]interface{}{
"foo": "old",
}
ui := new(cli.MockUi)
@ -323,7 +323,7 @@ func TestPush_preferAtlas(t *testing.T) {
t.Fatalf("bad: %#v", client.UpsertOptions)
}
variables := map[string]string{
variables := map[string]interface{}{
"foo": "old",
"bar": "foo",
}
@ -394,7 +394,7 @@ func TestPush_tfvars(t *testing.T) {
t.Fatalf("bad: %#v", client.UpsertOptions)
}
variables := map[string]string{
variables := map[string]interface{}{
"foo": "bar",
"bar": "foo",
}

View File

@ -45,7 +45,7 @@ type ContextOpts struct {
Providers map[string]ResourceProviderFactory
Provisioners map[string]ResourceProvisionerFactory
Targets []string
Variables map[string]string
Variables map[string]interface{}
UIInput UIInput
}
@ -68,7 +68,7 @@ type Context struct {
stateLock sync.RWMutex
targets []string
uiInput UIInput
variables map[string]string
variables map[string]interface{}
l sync.Mutex // Lock acquired during any task
parallelSem Semaphore
@ -121,7 +121,7 @@ func NewContext(opts *ContextOpts) (*Context, error) {
// Setup the variables. We first take the variables given to us.
// We then merge in the variables set in the environment.
variables := make(map[string]string)
variables := make(map[string]interface{})
for _, v := range os.Environ() {
if !strings.HasPrefix(v, VarEnvPrefix) {
continue
@ -506,12 +506,12 @@ func (c *Context) Module() *module.Tree {
// Variables will return the mapping of variables that were defined
// for this Context. If Input was called, this mapping may be different
// than what was given.
func (c *Context) Variables() map[string]string {
func (c *Context) Variables() map[string]interface{} {
return c.variables
}
// SetVariable sets a variable after a context has already been built.
func (c *Context) SetVariable(k, v string) {
func (c *Context) SetVariable(k string, v interface{}) {
c.variables[k] = v
}

View File

@ -843,7 +843,7 @@ func TestContext2Apply_compute(t *testing.T) {
t.Fatalf("err: %s", err)
}
ctx.variables = map[string]string{"value": "1"}
ctx.variables = map[string]interface{}{"value": "1"}
state, err := ctx.Apply()
if err != nil {
@ -1134,7 +1134,7 @@ func TestContext2Apply_mapVariableOverride(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"images.us-west-2": "overridden",
},
})
@ -1510,7 +1510,7 @@ func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"count": "2",
},
Destroy: true,
@ -1529,7 +1529,7 @@ func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"count": "5",
},
})
@ -1623,7 +1623,7 @@ func TestContext2Apply_multiVar(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"count": "3",
},
})
@ -1651,7 +1651,7 @@ func TestContext2Apply_multiVar(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"count": "1",
},
})
@ -1813,7 +1813,7 @@ func TestContext2Apply_Provisioner_compute(t *testing.T) {
Provisioners: map[string]ResourceProvisionerFactory{
"shell": testProvisionerFuncFixed(pr),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"value": "1",
},
})
@ -1937,7 +1937,7 @@ func TestContext2Apply_provisionerFail(t *testing.T) {
Provisioners: map[string]ResourceProvisionerFactory{
"shell": testProvisionerFuncFixed(pr),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"value": "1",
},
})
@ -2587,7 +2587,7 @@ func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
Provisioners: map[string]ResourceProvisionerFactory{
"shell": testProvisionerFuncFixed(pr),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"value": "1",
"pass": "test",
},
@ -2813,7 +2813,7 @@ func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"key_name": "foobarkey",
},
})
@ -4268,7 +4268,7 @@ func TestContext2Apply_vars(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "us-west-2",
"amis.us-east-1": "override",
},

View File

@ -18,7 +18,7 @@ func TestContext2Input(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "us-west-2",
"amis.us-east-1": "override",
},
@ -268,7 +268,7 @@ func TestContext2Input_providerOnly(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "us-west-2",
},
UIInput: input,
@ -323,7 +323,7 @@ func TestContext2Input_providerVars(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "bar",
},
UIInput: input,
@ -400,7 +400,7 @@ func TestContext2Input_varOnly(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "us-west-2",
},
UIInput: input,
@ -455,7 +455,7 @@ func TestContext2Input_varOnlyUnset(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "foovalue",
},
UIInput: input,
@ -497,7 +497,7 @@ func TestContext2Input_varWithDefault(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{},
Variables: map[string]interface{}{},
UIInput: input,
})
@ -543,7 +543,7 @@ func TestContext2Input_varPartiallyComputed(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "foovalue",
},
UIInput: input,

View File

@ -47,7 +47,7 @@ func TestContext2Plan_createBefore_maintainRoot(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"in": "a,b,c",
},
})
@ -289,7 +289,7 @@ func TestContext2Plan_moduleInputFromVar(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "52",
},
})
@ -584,7 +584,7 @@ func TestContext2Plan_moduleProviderDefaultsVar(t *testing.T) {
return p, nil
},
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "root",
},
})
@ -1187,7 +1187,7 @@ func TestContext2Plan_countVar(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"count": "3",
},
})
@ -2210,7 +2210,7 @@ func TestContext2Plan_provider(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "bar",
},
})
@ -2265,7 +2265,7 @@ func TestContext2Plan_ignoreChanges(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "ami-1234abcd",
},
State: s,

View File

@ -307,7 +307,7 @@ func TestContext2Validate_moduleProviderVar(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"provider_var": "bar",
},
})
@ -732,7 +732,7 @@ func TestContext2Validate_varRefFilled(t *testing.T) {
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
Variables: map[string]string{
Variables: map[string]interface{}{
"foo": "bar",
},
})

View File

@ -24,7 +24,7 @@ type Plan struct {
Diff *Diff
Module *module.Tree
State *State
Vars map[string]string
Vars map[string]interface{}
Targets []string
once sync.Once
@ -38,8 +38,13 @@ func (p *Plan) Context(opts *ContextOpts) (*Context, error) {
opts.Diff = p.Diff
opts.Module = p.Module
opts.State = p.State
opts.Variables = p.Vars
opts.Targets = p.Targets
opts.Variables = make(map[string]interface{})
for k, v := range p.Vars {
opts.Variables[k] = v
}
return NewContext(opts)
}
@ -65,7 +70,7 @@ func (p *Plan) init() {
}
if p.Vars == nil {
p.Vars = make(map[string]string)
p.Vars = make(map[string]interface{})
}
})
}

View File

@ -50,7 +50,7 @@ func TestReadWritePlan(t *testing.T) {
},
},
},
Vars: map[string]string{
Vars: map[string]interface{}{
"foo": "bar",
},
}

View File

@ -69,7 +69,7 @@ func (*SemanticCheckModulesExist) Check(g *dag.Graph, v dag.Vertex) error {
// smcUserVariables does all the semantic checks to verify that the
// variables given satisfy the configuration itself.
func smcUserVariables(c *config.Config, vs map[string]string) []error {
func smcUserVariables(c *config.Config, vs map[string]interface{}) []error {
var errs []error
cvs := make(map[string]*config.Variable)

View File

@ -14,13 +14,13 @@ func TestSMCUserVariables(t *testing.T) {
}
// Required variables set, optional variables unset
errs = smcUserVariables(c, map[string]string{"foo": "bar"})
errs = smcUserVariables(c, map[string]interface{}{"foo": "bar"})
if len(errs) != 0 {
t.Fatalf("err: %#v", errs)
}
// Mapping element override
errs = smcUserVariables(c, map[string]string{
errs = smcUserVariables(c, map[string]interface{}{
"foo": "bar",
"map.foo": "baz",
})
@ -29,7 +29,7 @@ func TestSMCUserVariables(t *testing.T) {
}
// Mapping complete override
errs = smcUserVariables(c, map[string]string{
errs = smcUserVariables(c, map[string]interface{}{
"foo": "bar",
"map": "baz",
})