command: -var flag works
This commit is contained in:
parent
272632ced0
commit
3534470ca3
|
@ -2,7 +2,6 @@ package command
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
@ -25,7 +24,7 @@ func (c *ApplyCommand) Run(args []string) int {
|
|||
|
||||
args = c.Meta.process(args)
|
||||
|
||||
cmdFlags := flag.NewFlagSet("apply", flag.ContinueOnError)
|
||||
cmdFlags := c.Meta.flagSet("apply")
|
||||
cmdFlags.BoolVar(&init, "init", false, "init")
|
||||
cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path")
|
||||
cmdFlags.StringVar(&stateOutPath, "state-out", "", "path")
|
||||
|
@ -207,6 +206,14 @@ Options:
|
|||
"-state". This can be used to preserve the old
|
||||
state.
|
||||
|
||||
-var 'foo=bar' Set a variable in the Terraform configuration. This
|
||||
flag can be set multiple times.
|
||||
|
||||
-var-file=foo Set variables in the Terraform configuration from
|
||||
a file. If "terraform.tfvars" is present, it will be
|
||||
automatically loaded if this flag is not specified.
|
||||
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -466,3 +466,41 @@ func TestApply_stateNoExist(t *testing.T) {
|
|||
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_vars(t *testing.T) {
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
actual := ""
|
||||
p.DiffFn = func(
|
||||
s *terraform.ResourceState,
|
||||
c *terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
|
||||
if v, ok := c.Config["value"]; ok {
|
||||
actual = v.(string)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-init",
|
||||
"-var", "foo=bar",
|
||||
"-state", statePath,
|
||||
testFixturePath("apply-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if actual != "bar" {
|
||||
t.Fatal("didn't work")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FlagVar is a flag.Value implementation for parsing user variables
|
||||
// from the command-line in the format of '-var key=value'.
|
||||
type FlagVar map[string]string
|
||||
|
||||
func (v *FlagVar) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v *FlagVar) Set(raw string) error {
|
||||
idx := strings.Index(raw, "=")
|
||||
if idx == -1 {
|
||||
return fmt.Errorf("No '=' value in arg: %s", raw)
|
||||
}
|
||||
|
||||
if *v == nil {
|
||||
*v = make(map[string]string)
|
||||
}
|
||||
|
||||
key, value := raw[0:idx], raw[idx+1:]
|
||||
(*v)[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
// FlagVarFile is a flag.Value implementation for parsing user variables
|
||||
// from the command line in the form of files. i.e. '-var-file=foo'
|
||||
type FlagVarFile map[string]string
|
||||
|
||||
func (v *FlagVarFile) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v *FlagVarFile) Set(raw string) error {
|
||||
// TODO
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFlagVar_impl(t *testing.T) {
|
||||
var _ flag.Value = new(FlagVar)
|
||||
}
|
||||
|
||||
func TestFlagVar(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Output map[string]string
|
||||
Error bool
|
||||
}{
|
||||
{
|
||||
"key=value",
|
||||
map[string]string{"key": "value"},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"key=",
|
||||
map[string]string{"key": ""},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"key=foo=bar",
|
||||
map[string]string{"key": "foo=bar"},
|
||||
false,
|
||||
},
|
||||
|
||||
{
|
||||
"key",
|
||||
nil,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
f := new(FlagVar)
|
||||
err := f.Set(tc.Input)
|
||||
if (err != nil) != tc.Error {
|
||||
t.Fatalf("bad error. Input: %#v", tc.Input)
|
||||
}
|
||||
|
||||
actual := map[string]string(*f)
|
||||
if !reflect.DeepEqual(actual, tc.Output) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
@ -19,6 +20,9 @@ type Meta struct {
|
|||
// This can be set by the command itself to provide extra hooks.
|
||||
extraHooks []terraform.Hook
|
||||
|
||||
// Variables for the context (private)
|
||||
variables map[string]string
|
||||
|
||||
color bool
|
||||
oldUi cli.Ui
|
||||
}
|
||||
|
@ -109,9 +113,29 @@ func (m *Meta) contextOpts() *terraform.ContextOpts {
|
|||
copy(opts.Hooks[1:], m.ContextOpts.Hooks)
|
||||
copy(opts.Hooks[len(m.ContextOpts.Hooks)+1:], m.extraHooks)
|
||||
println(fmt.Sprintf("%#v", opts.Hooks))
|
||||
|
||||
if len(m.variables) > 0 {
|
||||
vs := make(map[string]string)
|
||||
for k, v := range opts.Variables {
|
||||
vs[k] = v
|
||||
}
|
||||
for k, v := range m.variables {
|
||||
vs[k] = v
|
||||
}
|
||||
opts.Variables = vs
|
||||
}
|
||||
|
||||
return &opts
|
||||
}
|
||||
|
||||
// flags adds the meta flags to the given FlagSet.
|
||||
func (m *Meta) flagSet(n string) *flag.FlagSet {
|
||||
f := flag.NewFlagSet(n, flag.ContinueOnError)
|
||||
f.Var((*FlagVar)(&m.variables), "var", "variables")
|
||||
f.Var((*FlagVarFile)(&m.variables), "var-file", "variable file")
|
||||
return f
|
||||
}
|
||||
|
||||
// process will process the meta-parameters out of the arguments. This
|
||||
// will potentially modify the args in-place. It will return the resulting
|
||||
// slice.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -22,7 +21,7 @@ func (c *PlanCommand) Run(args []string) int {
|
|||
|
||||
args = c.Meta.process(args)
|
||||
|
||||
cmdFlags := flag.NewFlagSet("plan", flag.ContinueOnError)
|
||||
cmdFlags := c.Meta.flagSet("plan")
|
||||
cmdFlags.BoolVar(&destroy, "destroy", false, "destroy")
|
||||
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
|
||||
cmdFlags.StringVar(&outPath, "out", "", "path")
|
||||
|
@ -145,6 +144,13 @@ Options:
|
|||
up Terraform-managed resources. By default it will
|
||||
use the state "terraform.tfstate" if it exists.
|
||||
|
||||
-var 'foo=bar' Set a variable in the Terraform configuration. This
|
||||
flag can be set multiple times.
|
||||
|
||||
-var-file=foo Set variables in the Terraform configuration from
|
||||
a file. If "terraform.tfvars" is present, it will be
|
||||
automatically loaded if this flag is not specified.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -281,3 +281,37 @@ func TestPlan_stateDefault(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", p.DiffState)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlan_vars(t *testing.T) {
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &PlanCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
actual := ""
|
||||
p.DiffFn = func(
|
||||
s *terraform.ResourceState,
|
||||
c *terraform.ResourceConfig) (*terraform.ResourceDiff, error) {
|
||||
if v, ok := c.Config["value"]; ok {
|
||||
actual = v.(string)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-var", "foo=bar",
|
||||
testFixturePath("plan-vars"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if actual != "bar" {
|
||||
t.Fatal("didn't work")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -21,7 +20,7 @@ func (c *RefreshCommand) Run(args []string) int {
|
|||
|
||||
args = c.Meta.process(args)
|
||||
|
||||
cmdFlags := flag.NewFlagSet("refresh", flag.ContinueOnError)
|
||||
cmdFlags := c.Meta.flagSet("refresh")
|
||||
cmdFlags.StringVar(&statePath, "state", DefaultStateFilename, "path")
|
||||
cmdFlags.StringVar(&stateOutPath, "state-out", "", "path")
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
|
@ -128,6 +127,13 @@ Options:
|
|||
-state-out=path Path to write updated state file. By default, the
|
||||
"-state" path will be used.
|
||||
|
||||
-var 'foo=bar' Set a variable in the Terraform configuration. This
|
||||
flag can be set multiple times.
|
||||
|
||||
-var-file=foo Set variables in the Terraform configuration from
|
||||
a file. If "terraform.tfvars" is present, it will be
|
||||
automatically loaded if this flag is not specified.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -296,3 +296,40 @@ func TestRefresh_outPath(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefresh_var(t *testing.T) {
|
||||
state := &terraform.State{
|
||||
Resources: map[string]*terraform.ResourceState{
|
||||
"test_instance.foo": &terraform.ResourceState{
|
||||
ID: "bar",
|
||||
Type: "test_instance",
|
||||
},
|
||||
},
|
||||
}
|
||||
statePath := testStateFile(t, state)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &RefreshCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-var", "foo=bar",
|
||||
"-state", statePath,
|
||||
testFixturePath("refresh-var"),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if !p.ConfigureCalled {
|
||||
t.Fatal("configure should be called")
|
||||
}
|
||||
if p.ConfigureConfig.Config["value"].(string) != "bar" {
|
||||
t.Fatalf("bad: %#v", p.ConfigureConfig.Config)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
variable "foo" {}
|
||||
|
||||
resource "test_instance" "foo" {
|
||||
value = "${var.foo}"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
variable "foo" {}
|
||||
|
||||
resource "test_instance" "foo" {
|
||||
value = "${var.foo}"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
variable "foo" {}
|
||||
|
||||
provider "test" {
|
||||
value = "${var.foo}"
|
||||
}
|
||||
|
||||
resource "test_instance" "foo" {}
|
Loading…
Reference in New Issue