github.com/hooklift/terraform@v0.11.0-beta1.0.20171117000744-6786c1361ffe/command/validate.go (about)

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