github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/command/validate.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/terraform/tfdiags"
     9  
    10  	"github.com/hashicorp/terraform/config"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  // ValidateCommand is a Command implementation that validates the terraform files
    15  type ValidateCommand struct {
    16  	Meta
    17  }
    18  
    19  const defaultPath = "."
    20  
    21  func (c *ValidateCommand) Run(args []string) int {
    22  	args, err := c.Meta.process(args, true)
    23  	if err != nil {
    24  		return 1
    25  	}
    26  	var checkVars bool
    27  
    28  	cmdFlags := c.Meta.flagSet("validate")
    29  	cmdFlags.BoolVar(&checkVars, "check-variables", true, "check-variables")
    30  	cmdFlags.Usage = func() {
    31  		c.Ui.Error(c.Help())
    32  	}
    33  	if err := cmdFlags.Parse(args); err != nil {
    34  		return 1
    35  	}
    36  
    37  	args = cmdFlags.Args()
    38  
    39  	var dirPath string
    40  	if len(args) == 1 {
    41  		dirPath = args[0]
    42  	} else {
    43  		dirPath = "."
    44  	}
    45  	dir, err := filepath.Abs(dirPath)
    46  	if err != nil {
    47  		c.Ui.Error(fmt.Sprintf(
    48  			"Unable to locate directory %v\n", err.Error()))
    49  	}
    50  
    51  	// Check for user-supplied plugin path
    52  	if c.pluginPath, err = c.loadPluginPath(); err != nil {
    53  		c.Ui.Error(fmt.Sprintf("Error loading plugin path: %s", err))
    54  		return 1
    55  	}
    56  
    57  	rtnCode := c.validate(dir, checkVars)
    58  
    59  	return rtnCode
    60  }
    61  
    62  func (c *ValidateCommand) Synopsis() string {
    63  	return "Validates the Terraform files"
    64  }
    65  
    66  func (c *ValidateCommand) Help() string {
    67  	helpText := `
    68  Usage: terraform validate [options] [dir]
    69  
    70    Validate the terraform files in a directory. Validation includes a
    71    basic check of syntax as well as checking that all variables declared
    72    in the configuration are specified in one of the possible ways:
    73  
    74        -var foo=...
    75        -var-file=foo.vars
    76        TF_VAR_foo environment variable
    77        terraform.tfvars
    78        default value
    79  
    80    If dir is not specified, then the current directory will be used.
    81  
    82  Options:
    83  
    84    -check-variables=true If set to true (default), the command will check
    85                          whether all required variables have been specified.
    86  
    87    -no-color             If specified, output won't contain any color.
    88  
    89    -var 'foo=bar'        Set a variable in the Terraform configuration. This
    90                          flag can be set multiple times.
    91  
    92    -var-file=foo         Set variables in the Terraform configuration from
    93                          a file. If "terraform.tfvars" is present, it will be
    94                          automatically loaded if this flag is not specified.
    95  `
    96  	return strings.TrimSpace(helpText)
    97  }
    98  
    99  func (c *ValidateCommand) validate(dir string, checkVars bool) int {
   100  	var diags tfdiags.Diagnostics
   101  
   102  	cfg, err := config.LoadDir(dir)
   103  	if err != nil {
   104  		diags = diags.Append(err)
   105  		c.showDiagnostics(err)
   106  		return 1
   107  	}
   108  
   109  	diags = diags.Append(cfg.Validate())
   110  
   111  	if diags.HasErrors() {
   112  		c.showDiagnostics(diags)
   113  		return 1
   114  	}
   115  
   116  	if checkVars {
   117  		mod, modDiags := c.Module(dir)
   118  		diags = diags.Append(modDiags)
   119  		if modDiags.HasErrors() {
   120  			c.showDiagnostics(diags)
   121  			return 1
   122  		}
   123  
   124  		opts := c.contextOpts()
   125  		opts.Module = mod
   126  
   127  		tfCtx, err := terraform.NewContext(opts)
   128  		if err != nil {
   129  			diags = diags.Append(err)
   130  			c.showDiagnostics(diags)
   131  			return 1
   132  		}
   133  
   134  		diags = diags.Append(tfCtx.Validate())
   135  	}
   136  
   137  	c.showDiagnostics(diags)
   138  	if diags.HasErrors() {
   139  		return 1
   140  	}
   141  
   142  	return 0
   143  }