github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/validators.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "net" 6 "regexp" 7 "time" 8 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 func validateRdsId(v interface{}, k string) (ws []string, errors []error) { 13 value := v.(string) 14 if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) { 15 errors = append(errors, fmt.Errorf( 16 "only lowercase alphanumeric characters and hyphens allowed in %q", k)) 17 } 18 if !regexp.MustCompile(`^[a-z]`).MatchString(value) { 19 errors = append(errors, fmt.Errorf( 20 "first character of %q must be a letter", k)) 21 } 22 if regexp.MustCompile(`--`).MatchString(value) { 23 errors = append(errors, fmt.Errorf( 24 "%q cannot contain two consecutive hyphens", k)) 25 } 26 if regexp.MustCompile(`-$`).MatchString(value) { 27 errors = append(errors, fmt.Errorf( 28 "%q cannot end with a hyphen", k)) 29 } 30 return 31 } 32 33 func validateASGScheduleTimestamp(v interface{}, k string) (ws []string, errors []error) { 34 value := v.(string) 35 _, err := time.Parse(awsAutoscalingScheduleTimeLayout, value) 36 if err != nil { 37 errors = append(errors, fmt.Errorf( 38 "%q cannot be parsed as iso8601 Timestamp Format", value)) 39 } 40 41 return 42 } 43 44 // validateTagFilters confirms the "value" component of a tag filter is one of 45 // AWS's three allowed types. 46 func validateTagFilters(v interface{}, k string) (ws []string, errors []error) { 47 value := v.(string) 48 if value != "KEY_ONLY" && value != "VALUE_ONLY" && value != "KEY_AND_VALUE" { 49 errors = append(errors, fmt.Errorf( 50 "%q must be one of \"KEY_ONLY\", \"VALUE_ONLY\", or \"KEY_AND_VALUE\"", k)) 51 } 52 return 53 } 54 55 func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []error) { 56 value := v.(string) 57 if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) { 58 errors = append(errors, fmt.Errorf( 59 "only lowercase alphanumeric characters and hyphens allowed in %q", k)) 60 } 61 if !regexp.MustCompile(`^[a-z]`).MatchString(value) { 62 errors = append(errors, fmt.Errorf( 63 "first character of %q must be a letter", k)) 64 } 65 if regexp.MustCompile(`--`).MatchString(value) { 66 errors = append(errors, fmt.Errorf( 67 "%q cannot contain two consecutive hyphens", k)) 68 } 69 if regexp.MustCompile(`-$`).MatchString(value) { 70 errors = append(errors, fmt.Errorf( 71 "%q cannot end with a hyphen", k)) 72 } 73 if len(value) > 255 { 74 errors = append(errors, fmt.Errorf( 75 "%q cannot be greater than 255 characters", k)) 76 } 77 return 78 79 } 80 81 func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) { 82 value := v.(string) 83 viewTypes := map[string]bool{ 84 "KEYS_ONLY": true, 85 "NEW_IMAGE": true, 86 "OLD_IMAGE": true, 87 "NEW_AND_OLD_IMAGES": true, 88 } 89 90 if !viewTypes[value] { 91 errors = append(errors, fmt.Errorf("%q be a valid DynamoDB StreamViewType", k)) 92 } 93 return 94 } 95 96 func validateElbName(v interface{}, k string) (ws []string, errors []error) { 97 value := v.(string) 98 if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) { 99 errors = append(errors, fmt.Errorf( 100 "only alphanumeric characters and hyphens allowed in %q: %q", 101 k, value)) 102 } 103 if len(value) > 32 { 104 errors = append(errors, fmt.Errorf( 105 "%q cannot be longer than 32 characters: %q", k, value)) 106 } 107 if regexp.MustCompile(`^-`).MatchString(value) { 108 errors = append(errors, fmt.Errorf( 109 "%q cannot begin with a hyphen: %q", k, value)) 110 } 111 if regexp.MustCompile(`-$`).MatchString(value) { 112 errors = append(errors, fmt.Errorf( 113 "%q cannot end with a hyphen: %q", k, value)) 114 } 115 return 116 117 } 118 119 func validateEcrRepositoryName(v interface{}, k string) (ws []string, errors []error) { 120 value := v.(string) 121 if len(value) < 2 { 122 errors = append(errors, fmt.Errorf( 123 "%q must be at least 2 characters long: %q", k, value)) 124 } 125 if len(value) > 256 { 126 errors = append(errors, fmt.Errorf( 127 "%q cannot be longer than 256 characters: %q", k, value)) 128 } 129 130 // http://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_CreateRepository.html 131 pattern := `^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$` 132 if !regexp.MustCompile(pattern).MatchString(value) { 133 errors = append(errors, fmt.Errorf( 134 "%q doesn't comply with restrictions (%q): %q", 135 k, pattern, value)) 136 } 137 138 return 139 } 140 141 func validateCloudWatchEventRuleName(v interface{}, k string) (ws []string, errors []error) { 142 value := v.(string) 143 if len(value) > 64 { 144 errors = append(errors, fmt.Errorf( 145 "%q cannot be longer than 64 characters: %q", k, value)) 146 } 147 148 // http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutRule.html 149 pattern := `^[\.\-_A-Za-z0-9]+$` 150 if !regexp.MustCompile(pattern).MatchString(value) { 151 errors = append(errors, fmt.Errorf( 152 "%q doesn't comply with restrictions (%q): %q", 153 k, pattern, value)) 154 } 155 156 return 157 } 158 159 func validateMaxLength(length int) schema.SchemaValidateFunc { 160 return func(v interface{}, k string) (ws []string, errors []error) { 161 value := v.(string) 162 if len(value) > length { 163 errors = append(errors, fmt.Errorf( 164 "%q cannot be longer than %d characters: %q", k, length, value)) 165 } 166 return 167 } 168 } 169 170 func validateCloudWatchEventTargetId(v interface{}, k string) (ws []string, errors []error) { 171 value := v.(string) 172 if len(value) > 64 { 173 errors = append(errors, fmt.Errorf( 174 "%q cannot be longer than 64 characters: %q", k, value)) 175 } 176 177 // http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_Target.html 178 pattern := `^[\.\-_A-Za-z0-9]+$` 179 if !regexp.MustCompile(pattern).MatchString(value) { 180 errors = append(errors, fmt.Errorf( 181 "%q doesn't comply with restrictions (%q): %q", 182 k, pattern, value)) 183 } 184 185 return 186 } 187 188 func validateLambdaFunctionName(v interface{}, k string) (ws []string, errors []error) { 189 value := v.(string) 190 if len(value) > 140 { 191 errors = append(errors, fmt.Errorf( 192 "%q cannot be longer than 140 characters: %q", k, value)) 193 } 194 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 195 pattern := `^(arn:aws:lambda:)?([a-z]{2}-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?$` 196 if !regexp.MustCompile(pattern).MatchString(value) { 197 errors = append(errors, fmt.Errorf( 198 "%q doesn't comply with restrictions (%q): %q", 199 k, pattern, value)) 200 } 201 202 return 203 } 204 205 func validateLambdaQualifier(v interface{}, k string) (ws []string, errors []error) { 206 value := v.(string) 207 if len(value) > 128 { 208 errors = append(errors, fmt.Errorf( 209 "%q cannot be longer than 128 characters: %q", k, value)) 210 } 211 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 212 pattern := `^[a-zA-Z0-9$_]+$` 213 if !regexp.MustCompile(pattern).MatchString(value) { 214 errors = append(errors, fmt.Errorf( 215 "%q doesn't comply with restrictions (%q): %q", 216 k, pattern, value)) 217 } 218 219 return 220 } 221 222 func validateLambdaPermissionAction(v interface{}, k string) (ws []string, errors []error) { 223 value := v.(string) 224 225 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 226 pattern := `^(lambda:[*]|lambda:[a-zA-Z]+|[*])$` 227 if !regexp.MustCompile(pattern).MatchString(value) { 228 errors = append(errors, fmt.Errorf( 229 "%q doesn't comply with restrictions (%q): %q", 230 k, pattern, value)) 231 } 232 233 return 234 } 235 236 func validateAwsAccountId(v interface{}, k string) (ws []string, errors []error) { 237 value := v.(string) 238 239 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 240 pattern := `^\d{12}$` 241 if !regexp.MustCompile(pattern).MatchString(value) { 242 errors = append(errors, fmt.Errorf( 243 "%q doesn't look like AWS Account ID (exactly 12 digits): %q", 244 k, value)) 245 } 246 247 return 248 } 249 250 func validateArn(v interface{}, k string) (ws []string, errors []error) { 251 value := v.(string) 252 253 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 254 pattern := `^arn:aws:([a-zA-Z0-9\-])+:([a-z]{2}-[a-z]+-\d{1})?:(\d{12})?:(.*)$` 255 if !regexp.MustCompile(pattern).MatchString(value) { 256 errors = append(errors, fmt.Errorf( 257 "%q doesn't look like a valid ARN (%q): %q", 258 k, pattern, value)) 259 } 260 261 return 262 } 263 264 func validatePolicyStatementId(v interface{}, k string) (ws []string, errors []error) { 265 value := v.(string) 266 267 if len(value) > 100 { 268 errors = append(errors, fmt.Errorf( 269 "%q cannot be longer than 100 characters: %q", k, value)) 270 } 271 272 // http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html 273 pattern := `^[a-zA-Z0-9-_]+$` 274 if !regexp.MustCompile(pattern).MatchString(value) { 275 errors = append(errors, fmt.Errorf( 276 "%q doesn't look like a valid statement ID (%q): %q", 277 k, pattern, value)) 278 } 279 280 return 281 } 282 283 // validateCIDRNetworkAddress ensures that the string value is a valid CIDR that 284 // represents a network address - it adds an error otherwise 285 func validateCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) { 286 value := v.(string) 287 _, ipnet, err := net.ParseCIDR(value) 288 if err != nil { 289 errors = append(errors, fmt.Errorf( 290 "%q must contain a valid CIDR, got error parsing: %s", k, err)) 291 return 292 } 293 294 if ipnet == nil || value != ipnet.String() { 295 errors = append(errors, fmt.Errorf( 296 "%q must contain a valid network CIDR, expected %q, got %q", 297 k, ipnet, value)) 298 } 299 300 return 301 } 302 303 func validateHTTPMethod(v interface{}, k string) (ws []string, errors []error) { 304 value := v.(string) 305 if value != "GET" && value != "HEAD" && value != "OPTIONS" && value != "PUT" && value != "POST" && value != "PATCH" && value != "DELETE" { 306 errors = append(errors, fmt.Errorf( 307 "%q must be one of 'GET', 'HEAD', 'OPTIONS', 'PUT', 'POST', 'PATCH', 'DELETE'", k)) 308 } 309 return 310 } 311 312 func validateLogMetricFilterName(v interface{}, k string) (ws []string, errors []error) { 313 value := v.(string) 314 315 if len(value) > 512 { 316 errors = append(errors, fmt.Errorf( 317 "%q cannot be longer than 512 characters: %q", k, value)) 318 } 319 320 // http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutMetricFilter.html 321 pattern := `^[^:*]+$` 322 if !regexp.MustCompile(pattern).MatchString(value) { 323 errors = append(errors, fmt.Errorf( 324 "%q isn't a valid log metric name (must not contain colon nor asterisk): %q", 325 k, value)) 326 } 327 328 return 329 } 330 331 func validateLogMetricFilterTransformationName(v interface{}, k string) (ws []string, errors []error) { 332 value := v.(string) 333 334 if len(value) > 255 { 335 errors = append(errors, fmt.Errorf( 336 "%q cannot be longer than 255 characters: %q", k, value)) 337 } 338 339 // http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_MetricTransformation.html 340 pattern := `^[^:*$]*$` 341 if !regexp.MustCompile(pattern).MatchString(value) { 342 errors = append(errors, fmt.Errorf( 343 "%q isn't a valid log metric transformation name (must not contain"+ 344 " colon, asterisk nor dollar sign): %q", 345 k, value)) 346 } 347 348 return 349 } 350 351 func validateLogGroupName(v interface{}, k string) (ws []string, errors []error) { 352 value := v.(string) 353 354 if len(value) > 512 { 355 errors = append(errors, fmt.Errorf( 356 "%q cannot be longer than 512 characters: %q", k, value)) 357 } 358 359 // http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html 360 pattern := `^[\.\-_/#A-Za-z0-9]+$` 361 if !regexp.MustCompile(pattern).MatchString(value) { 362 errors = append(errors, fmt.Errorf( 363 "%q isn't a valid log group name (alphanumeric characters, underscores,"+ 364 " hyphens, slashes, hash signs and dots are allowed): %q", 365 k, value)) 366 } 367 368 return 369 }