github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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 err = nil 46 47 if count < 0 { 48 errs = append(errs, fmt.Errorf( 49 "Count is less than zero: %d", count)) 50 } 51 52 RETURN: 53 if len(errs) != 0 { 54 err = &EvalValidateError{ 55 Errors: errs, 56 } 57 } 58 return nil, err 59 } 60 61 // EvalValidateProvider is an EvalNode implementation that validates 62 // the configuration of a resource. 63 type EvalValidateProvider struct { 64 Provider *ResourceProvider 65 Config **ResourceConfig 66 } 67 68 func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) { 69 provider := *n.Provider 70 config := *n.Config 71 72 warns, errs := provider.Validate(config) 73 if len(warns) == 0 && len(errs) == 0 { 74 return nil, nil 75 } 76 77 return nil, &EvalValidateError{ 78 Warnings: warns, 79 Errors: errs, 80 } 81 } 82 83 // EvalValidateProvisioner is an EvalNode implementation that validates 84 // the configuration of a resource. 85 type EvalValidateProvisioner struct { 86 Provisioner *ResourceProvisioner 87 Config **ResourceConfig 88 } 89 90 func (n *EvalValidateProvisioner) Eval(ctx EvalContext) (interface{}, error) { 91 provisioner := *n.Provisioner 92 config := *n.Config 93 warns, errs := provisioner.Validate(config) 94 if len(warns) == 0 && len(errs) == 0 { 95 return nil, nil 96 } 97 98 return nil, &EvalValidateError{ 99 Warnings: warns, 100 Errors: errs, 101 } 102 } 103 104 // EvalValidateResource is an EvalNode implementation that validates 105 // the configuration of a resource. 106 type EvalValidateResource struct { 107 Provider *ResourceProvider 108 Config **ResourceConfig 109 ResourceName string 110 ResourceType string 111 ResourceMode config.ResourceMode 112 113 // IgnoreWarnings means that warnings will not be passed through. This allows 114 // "just-in-time" passes of validation to continue execution through warnings. 115 IgnoreWarnings bool 116 } 117 118 func (n *EvalValidateResource) Eval(ctx EvalContext) (interface{}, error) { 119 provider := *n.Provider 120 cfg := *n.Config 121 var warns []string 122 var errs []error 123 // Provider entry point varies depending on resource mode, because 124 // managed resources and data resources are two distinct concepts 125 // in the provider abstraction. 126 switch n.ResourceMode { 127 case config.ManagedResourceMode: 128 warns, errs = provider.ValidateResource(n.ResourceType, cfg) 129 case config.DataResourceMode: 130 warns, errs = provider.ValidateDataSource(n.ResourceType, cfg) 131 } 132 133 // If the resource name doesn't match the name regular 134 // expression, show an error. 135 if !config.NameRegexp.Match([]byte(n.ResourceName)) { 136 errs = append(errs, fmt.Errorf( 137 "%s: resource name can only contain letters, numbers, "+ 138 "dashes, and underscores.", n.ResourceName)) 139 } 140 141 if (len(warns) == 0 || n.IgnoreWarnings) && len(errs) == 0 { 142 return nil, nil 143 } 144 145 return nil, &EvalValidateError{ 146 Warnings: warns, 147 Errors: errs, 148 } 149 }