command/meta: validate config immediately
* config: test for validating multi-vars (passes) * command/plan: test invalid run * command/meta: validate module on load
This commit is contained in:
parent
d31656af91
commit
609219fc65
|
@ -2,6 +2,7 @@ package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
|
@ -27,7 +28,11 @@ const DefaultBackupExtension = ".backup"
|
||||||
const DefaultParallelism = 10
|
const DefaultParallelism = 10
|
||||||
|
|
||||||
func validateContext(ctx *terraform.Context, ui cli.Ui) bool {
|
func validateContext(ctx *terraform.Context, ui cli.Ui) bool {
|
||||||
if ws, es := ctx.Validate(); len(ws) > 0 || len(es) > 0 {
|
log.Println("[INFO] Validating the context...")
|
||||||
|
ws, es := ctx.Validate()
|
||||||
|
log.Printf("[INFO] Validation result: %d warnings, %d errors", len(ws), len(es))
|
||||||
|
|
||||||
|
if len(ws) > 0 || len(es) > 0 {
|
||||||
ui.Output(
|
ui.Output(
|
||||||
"There are warnings and/or errors related to your configuration. Please\n" +
|
"There are warnings and/or errors related to your configuration. Please\n" +
|
||||||
"fix these before continuing.\n")
|
"fix these before continuing.\n")
|
||||||
|
|
|
@ -165,6 +165,11 @@ func (m *Meta) Context(copts contextOpts) (*terraform.Context, bool, error) {
|
||||||
return nil, false, fmt.Errorf("Error downloading modules: %s", err)
|
return nil, false, fmt.Errorf("Error downloading modules: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate the module right away
|
||||||
|
if err := mod.Validate(); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
opts.Module = mod
|
opts.Module = mod
|
||||||
opts.Parallelism = copts.Parallelism
|
opts.Parallelism = copts.Parallelism
|
||||||
opts.State = state.State()
|
opts.State = state.State()
|
||||||
|
|
|
@ -395,6 +395,40 @@ func TestPlan_statePast(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPlan_validate(t *testing.T) {
|
||||||
|
// This is triggered by not asking for input so we have to set this to false
|
||||||
|
test = false
|
||||||
|
defer func() { test = true }()
|
||||||
|
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if err := os.Chdir(testFixturePath("plan-invalid")); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
defer os.Chdir(cwd)
|
||||||
|
|
||||||
|
p := testProvider()
|
||||||
|
ui := new(cli.MockUi)
|
||||||
|
c := &PlanCommand{
|
||||||
|
Meta: Meta{
|
||||||
|
ContextOpts: testCtxConfig(p),
|
||||||
|
Ui: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
args := []string{}
|
||||||
|
if code := c.Run(args); code != 1 {
|
||||||
|
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := ui.ErrorWriter.String()
|
||||||
|
if !strings.Contains(actual, "can't reference") {
|
||||||
|
t.Fatalf("bad: %s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPlan_vars(t *testing.T) {
|
func TestPlan_vars(t *testing.T) {
|
||||||
p := testProvider()
|
p := testProvider()
|
||||||
ui := new(cli.MockUi)
|
ui := new(cli.MockUi)
|
||||||
|
|
|
@ -766,7 +766,6 @@ func pushTFVars() []atlas.TFVar {
|
||||||
{"bar", "foo", false},
|
{"bar", "foo", false},
|
||||||
{"baz", `{
|
{"baz", `{
|
||||||
A = "a"
|
A = "a"
|
||||||
interp = "${file("t.txt")}"
|
|
||||||
}`, true},
|
}`, true},
|
||||||
{"fob", `["a", "quotes \"in\" quotes"]`, true},
|
{"fob", `["a", "quotes \"in\" quotes"]`, true},
|
||||||
{"foo", "bar", false},
|
{"foo", "bar", false},
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
resource "test_instance" "foo" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "bar" {
|
||||||
|
count = "${length(test_instance.foo.*.id)}"
|
||||||
|
}
|
|
@ -7,7 +7,6 @@ variable "baz" {
|
||||||
|
|
||||||
default = {
|
default = {
|
||||||
"A" = "a"
|
"A" = "a"
|
||||||
interp = "${file("t.txt")}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,13 @@ func TestConfigValidate_countResourceVar(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfigValidate_countResourceVarMulti(t *testing.T) {
|
||||||
|
c := testConfig(t, "validate-count-resource-var-multi")
|
||||||
|
if err := c.Validate(); err == nil {
|
||||||
|
t.Fatal("should not be valid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigValidate_countUserVar(t *testing.T) {
|
func TestConfigValidate_countUserVar(t *testing.T) {
|
||||||
c := testConfig(t, "validate-count-user-var")
|
c := testConfig(t, "validate-count-user-var")
|
||||||
if err := c.Validate(); err != nil {
|
if err := c.Validate(); err != nil {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
resource "aws_instance" "foo" {}
|
||||||
|
|
||||||
|
resource "aws_instance" "web" {
|
||||||
|
count = "${length(aws_instance.foo.*.bar)}"
|
||||||
|
}
|
Loading…
Reference in New Issue