github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/terraform/eval_validate.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  )
     8  
     9  // EvalValidateError is the error structure returned if there were
    10  // validation errors.
    11  type EvalValidateError struct {
    12  	Warnings []string
    13  	Errors   []error
    14  }
    15  
    16  func (e *EvalValidateError) Error() string {
    17  	return fmt.Sprintf("Warnings: %s. Errors: %s", e.Warnings, e.Errors)
    18  }
    19  
    20  // EvalValidateCount is an EvalNode implementation that validates
    21  // the count of a resource.
    22  type EvalValidateCount struct {
    23  	Resource *config.Resource
    24  }
    25  
    26  // TODO: test
    27  func (n *EvalValidateCount) Eval(ctx EvalContext) (interface{}, error) {
    28  	var count int
    29  	var errs []error
    30  	var err error
    31  	if _, err := ctx.Interpolate(n.Resource.RawCount, nil); err != nil {
    32  		errs = append(errs, fmt.Errorf(
    33  			"Failed to interpolate count: %s", err))
    34  		goto RETURN
    35  	}
    36  
    37  	count, err = n.Resource.Count()
    38  	if err != nil {
    39  		// If we can't get the count during validation, then
    40  		// just replace it with the number 1.
    41  		c := n.Resource.RawCount.Config()
    42  		c[n.Resource.RawCount.Key] = "1"
    43  		count = 1
    44  	}
    45  
    46  	if count < 0 {
    47  		errs = append(errs, fmt.Errorf(
    48  			"Count is less than zero: %d", count))
    49  	}
    50  
    51  RETURN:
    52  	return nil, &EvalValidateError{
    53  		Errors: errs,
    54  	}
    55  }
    56  
    57  // EvalValidateProvider is an EvalNode implementation that validates
    58  // the configuration of a resource.
    59  type EvalValidateProvider struct {
    60  	ProviderName string
    61  	Provider     *ResourceProvider
    62  	Config       **ResourceConfig
    63  }
    64  
    65  func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
    66  	provider := *n.Provider
    67  	config := *n.Config
    68  
    69  	// Get the parent configuration if there is one
    70  	if parent := ctx.ParentProviderConfig(n.ProviderName); parent != nil {
    71  		merged := parent.raw.Merge(config.raw)
    72  		config = NewResourceConfig(merged)
    73  	}
    74  
    75  	warns, errs := provider.Validate(config)
    76  	if len(warns) == 0 && len(errs) == 0 {
    77  		return nil, nil
    78  	}
    79  
    80  	return nil, &EvalValidateError{
    81  		Warnings: warns,
    82  		Errors:   errs,
    83  	}
    84  }
    85  
    86  // EvalValidateProvisioner is an EvalNode implementation that validates
    87  // the configuration of a resource.
    88  type EvalValidateProvisioner struct {
    89  	Provisioner *ResourceProvisioner
    90  	Config      **ResourceConfig
    91  }
    92  
    93  func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) {
    94  	provisioner := *n.Provisioner
    95  	config := *n.Config
    96  	warns, errs := provisioner.Validate(config)
    97  	if len(warns) == 0 && len(errs) == 0 {
    98  		return nil, nil
    99  	}
   100  
   101  	return nil, &EvalValidateError{
   102  		Warnings: warns,
   103  		Errors:   errs,
   104  	}
   105  }
   106  
   107  // EvalValidateResource is an EvalNode implementation that validates
   108  // the configuration of a resource.
   109  type EvalValidateResource struct {
   110  	Provider     *ResourceProvider
   111  	Config       **ResourceConfig
   112  	ResourceName string
   113  	ResourceType string
   114  }
   115  
   116  func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) {
   117  	// TODO: test
   118  
   119  	provider := *n.Provider
   120  	cfg := *n.Config
   121  	warns, errs := provider.ValidateResource(n.ResourceType, cfg)
   122  
   123  	// If the resouce name doesn't match the name regular
   124  	// expression, show a warning.
   125  	if !config.NameRegexp.Match([]byte(n.ResourceName)) {
   126  		warns = append(warns, fmt.Sprintf(
   127  			"%s: resource name can only contain letters, numbers, "+
   128  				"dashes, and underscores.\n"+
   129  				"This will be an error in Terraform 0.4",
   130  			n.ResourceName))
   131  	}
   132  
   133  	if len(warns) == 0 && len(errs) == 0 {
   134  		return nil, nil
   135  	}
   136  
   137  	return nil, &EvalValidateError{
   138  		Warnings: warns,
   139  		Errors:   errs,
   140  	}
   141  }