github.com/joshgarnett/terraform@v0.5.4-0.20160219181435-92dc20bb3594/builtin/providers/aws/validators.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "regexp" 6 "time" 7 8 "github.com/hashicorp/terraform/helper/schema" 9 ) 10 11 func validateRdsId(v interface{}, k string) (ws []string, errors []error) { 12 value := v.(string) 13 if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) { 14 errors = append(errors, fmt.Errorf( 15 "only lowercase alphanumeric characters and hyphens allowed in %q", k)) 16 } 17 if !regexp.MustCompile(`^[a-z]`).MatchString(value) { 18 errors = append(errors, fmt.Errorf( 19 "first character of %q must be a letter", k)) 20 } 21 if regexp.MustCompile(`--`).MatchString(value) { 22 errors = append(errors, fmt.Errorf( 23 "%q cannot contain two consecutive hyphens", k)) 24 } 25 if regexp.MustCompile(`-$`).MatchString(value) { 26 errors = append(errors, fmt.Errorf( 27 "%q cannot end with a hyphen", k)) 28 } 29 return 30 } 31 32 func validateASGScheduleTimestamp(v interface{}, k string) (ws []string, errors []error) { 33 value := v.(string) 34 _, err := time.Parse(awsAutoscalingScheduleTimeLayout, value) 35 if err != nil { 36 errors = append(errors, fmt.Errorf( 37 "%q cannot be parsed as iso8601 Timestamp Format", value)) 38 } 39 40 return 41 } 42 43 // validateTagFilters confirms the "value" component of a tag filter is one of 44 // AWS's three allowed types. 45 func validateTagFilters(v interface{}, k string) (ws []string, errors []error) { 46 value := v.(string) 47 if value != "KEY_ONLY" && value != "VALUE_ONLY" && value != "KEY_AND_VALUE" { 48 errors = append(errors, fmt.Errorf( 49 "%q must be one of \"KEY_ONLY\", \"VALUE_ONLY\", or \"KEY_AND_VALUE\"", k)) 50 } 51 return 52 } 53 54 func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []error) { 55 value := v.(string) 56 if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) { 57 errors = append(errors, fmt.Errorf( 58 "only lowercase alphanumeric characters and hyphens allowed in %q", k)) 59 } 60 if !regexp.MustCompile(`^[a-z]`).MatchString(value) { 61 errors = append(errors, fmt.Errorf( 62 "first character of %q must be a letter", k)) 63 } 64 if regexp.MustCompile(`--`).MatchString(value) { 65 errors = append(errors, fmt.Errorf( 66 "%q cannot contain two consecutive hyphens", k)) 67 } 68 if regexp.MustCompile(`-$`).MatchString(value) { 69 errors = append(errors, fmt.Errorf( 70 "%q cannot end with a hyphen", k)) 71 } 72 if len(value) > 255 { 73 errors = append(errors, fmt.Errorf( 74 "%q cannot be greater than 255 characters", k)) 75 } 76 return 77 78 } 79 80 func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) { 81 value := v.(string) 82 viewTypes := map[string]bool{ 83 "KEYS_ONLY": true, 84 "NEW_IMAGE": true, 85 "OLD_IMAGE": true, 86 "NEW_AND_OLD_IMAGES": true, 87 } 88 89 if !viewTypes[value] { 90 errors = append(errors, fmt.Errorf("%q be a valid DynamoDB StreamViewType", k)) 91 } 92 return 93 } 94 95 func validateElbName(v interface{}, k string) (ws []string, errors []error) { 96 value := v.(string) 97 if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) { 98 errors = append(errors, fmt.Errorf( 99 "only alphanumeric characters and hyphens allowed in %q: %q", 100 k, value)) 101 } 102 if len(value) > 32 { 103 errors = append(errors, fmt.Errorf( 104 "%q cannot be longer than 32 characters: %q", k, value)) 105 } 106 if regexp.MustCompile(`^-`).MatchString(value) { 107 errors = append(errors, fmt.Errorf( 108 "%q cannot begin with a hyphen: %q", k, value)) 109 } 110 if regexp.MustCompile(`-$`).MatchString(value) { 111 errors = append(errors, fmt.Errorf( 112 "%q cannot end with a hyphen: %q", k, value)) 113 } 114 return 115 116 } 117 118 func validateEcrRepositoryName(v interface{}, k string) (ws []string, errors []error) { 119 value := v.(string) 120 if len(value) < 2 { 121 errors = append(errors, fmt.Errorf( 122 "%q must be at least 2 characters long: %q", k, value)) 123 } 124 if len(value) > 256 { 125 errors = append(errors, fmt.Errorf( 126 "%q cannot be longer than 256 characters: %q", k, value)) 127 } 128 129 // http://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_CreateRepository.html 130 pattern := `^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$` 131 if !regexp.MustCompile(pattern).MatchString(value) { 132 errors = append(errors, fmt.Errorf( 133 "%q doesn't comply with restrictions (%q): %q", 134 k, pattern, value)) 135 } 136 137 return 138 } 139 140 func validateCloudWatchEventRuleName(v interface{}, k string) (ws []string, errors []error) { 141 value := v.(string) 142 if len(value) > 64 { 143 errors = append(errors, fmt.Errorf( 144 "%q cannot be longer than 64 characters: %q", k, value)) 145 } 146 147 // http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutRule.html 148 pattern := `^[\.\-_A-Za-z0-9]+$` 149 if !regexp.MustCompile(pattern).MatchString(value) { 150 errors = append(errors, fmt.Errorf( 151 "%q doesn't comply with restrictions (%q): %q", 152 k, pattern, value)) 153 } 154 155 return 156 } 157 158 func validateMaxLength(length int) schema.SchemaValidateFunc { 159 return func(v interface{}, k string) (ws []string, errors []error) { 160 value := v.(string) 161 if len(value) > length { 162 errors = append(errors, fmt.Errorf( 163 "%q cannot be longer than %d characters: %q", k, length, value)) 164 } 165 return 166 } 167 } 168 169 func validateCloudWatchEventTargetId(v interface{}, k string) (ws []string, errors []error) { 170 value := v.(string) 171 if len(value) > 64 { 172 errors = append(errors, fmt.Errorf( 173 "%q cannot be longer than 64 characters: %q", k, value)) 174 } 175 176 // http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_Target.html 177 pattern := `^[\.\-_A-Za-z0-9]+$` 178 if !regexp.MustCompile(pattern).MatchString(value) { 179 errors = append(errors, fmt.Errorf( 180 "%q doesn't comply with restrictions (%q): %q", 181 k, pattern, value)) 182 } 183 184 return 185 } 186 187 func validateLambdaFunctionName(v interface{}, k string) (ws []string, errors []error) { 188 value := v.(string) 189 if len(value) > 140 { 190 errors = append(errors, fmt.Errorf( 191 "%q cannot be longer than 140 characters: %q", k, value)) 192 } 193 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 194 pattern := `^(arn:aws:lambda:)?([a-z]{2}-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?$` 195 if !regexp.MustCompile(pattern).MatchString(value) { 196 errors = append(errors, fmt.Errorf( 197 "%q doesn't comply with restrictions (%q): %q", 198 k, pattern, value)) 199 } 200 201 return 202 } 203 204 func validateLambdaQualifier(v interface{}, k string) (ws []string, errors []error) { 205 value := v.(string) 206 if len(value) > 128 { 207 errors = append(errors, fmt.Errorf( 208 "%q cannot be longer than 128 characters: %q", k, value)) 209 } 210 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 211 pattern := `^[a-zA-Z0-9$_]+$` 212 if !regexp.MustCompile(pattern).MatchString(value) { 213 errors = append(errors, fmt.Errorf( 214 "%q doesn't comply with restrictions (%q): %q", 215 k, pattern, value)) 216 } 217 218 return 219 } 220 221 func validateLambdaPermissionAction(v interface{}, k string) (ws []string, errors []error) { 222 value := v.(string) 223 224 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 225 pattern := `^(lambda:[*]|lambda:[a-zA-Z]+|[*])$` 226 if !regexp.MustCompile(pattern).MatchString(value) { 227 errors = append(errors, fmt.Errorf( 228 "%q doesn't comply with restrictions (%q): %q", 229 k, pattern, value)) 230 } 231 232 return 233 } 234 235 func validateAwsAccountId(v interface{}, k string) (ws []string, errors []error) { 236 value := v.(string) 237 238 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 239 pattern := `^\d{12}$` 240 if !regexp.MustCompile(pattern).MatchString(value) { 241 errors = append(errors, fmt.Errorf( 242 "%q doesn't look like AWS Account ID (exactly 12 digits): %q", 243 k, value)) 244 } 245 246 return 247 } 248 249 func validateArn(v interface{}, k string) (ws []string, errors []error) { 250 value := v.(string) 251 252 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 253 pattern := `^arn:aws:([a-zA-Z0-9\-])+:([a-z]{2}-[a-z]+-\d{1})?:(\d{12})?:(.*)$` 254 if !regexp.MustCompile(pattern).MatchString(value) { 255 errors = append(errors, fmt.Errorf( 256 "%q doesn't look like a valid ARN (%q): %q", 257 k, pattern, value)) 258 } 259 260 return 261 } 262 263 func validatePolicyStatementId(v interface{}, k string) (ws []string, errors []error) { 264 value := v.(string) 265 266 if len(value) > 100 { 267 errors = append(errors, fmt.Errorf( 268 "%q cannot be longer than 100 characters: %q", k, value)) 269 } 270 271 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 272 pattern := `^[a-zA-Z0-9-_]+$` 273 if !regexp.MustCompile(pattern).MatchString(value) { 274 errors = append(errors, fmt.Errorf( 275 "%q doesn't look like a valid statement ID (%q): %q", 276 k, pattern, value)) 277 } 278 279 return 280 }