github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/alicloud/validators.go (about) 1 package alicloud 2 3 import ( 4 "fmt" 5 "net" 6 "strconv" 7 "strings" 8 9 "github.com/denverdino/aliyungo/common" 10 "github.com/denverdino/aliyungo/ecs" 11 "github.com/denverdino/aliyungo/slb" 12 "github.com/hashicorp/terraform/helper/schema" 13 "regexp" 14 ) 15 16 // common 17 func validateInstancePort(v interface{}, k string) (ws []string, errors []error) { 18 value := v.(int) 19 if value < 1 || value > 65535 { 20 errors = append(errors, fmt.Errorf( 21 "%q must be a valid port between 1 and 65535", 22 k)) 23 return 24 } 25 return 26 } 27 28 func validateInstanceProtocol(v interface{}, k string) (ws []string, errors []error) { 29 protocol := v.(string) 30 if !isProtocolValid(protocol) { 31 errors = append(errors, fmt.Errorf( 32 "%q is an invalid value. Valid values are either http, https, tcp or udp", 33 k)) 34 return 35 } 36 return 37 } 38 39 // ecs 40 func validateDiskCategory(v interface{}, k string) (ws []string, errors []error) { 41 category := ecs.DiskCategory(v.(string)) 42 if category != ecs.DiskCategoryCloud && category != ecs.DiskCategoryCloudEfficiency && category != ecs.DiskCategoryCloudSSD { 43 errors = append(errors, fmt.Errorf("%s must be one of %s %s %s", k, ecs.DiskCategoryCloud, ecs.DiskCategoryCloudEfficiency, ecs.DiskCategoryCloudSSD)) 44 } 45 46 return 47 } 48 49 func validateInstanceName(v interface{}, k string) (ws []string, errors []error) { 50 value := v.(string) 51 if len(value) < 2 || len(value) > 128 { 52 errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k)) 53 } 54 55 if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") { 56 errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k)) 57 } 58 59 return 60 } 61 62 func validateInstanceDescription(v interface{}, k string) (ws []string, errors []error) { 63 value := v.(string) 64 if len(value) < 2 || len(value) > 256 { 65 errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k)) 66 67 } 68 return 69 } 70 71 func validateDiskName(v interface{}, k string) (ws []string, errors []error) { 72 value := v.(string) 73 74 if value == "" { 75 return 76 } 77 78 if len(value) < 2 || len(value) > 128 { 79 errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k)) 80 } 81 82 if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") { 83 errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k)) 84 } 85 86 return 87 } 88 89 func validateDiskDescription(v interface{}, k string) (ws []string, errors []error) { 90 value := v.(string) 91 if len(value) < 2 || len(value) > 256 { 92 errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k)) 93 94 } 95 return 96 } 97 98 //security group 99 func validateSecurityGroupName(v interface{}, k string) (ws []string, errors []error) { 100 value := v.(string) 101 if len(value) < 2 || len(value) > 128 { 102 errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k)) 103 } 104 105 if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") { 106 errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k)) 107 } 108 109 return 110 } 111 112 func validateSecurityGroupDescription(v interface{}, k string) (ws []string, errors []error) { 113 value := v.(string) 114 if len(value) < 2 || len(value) > 256 { 115 errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k)) 116 117 } 118 return 119 } 120 121 func validateSecurityRuleType(v interface{}, k string) (ws []string, errors []error) { 122 rt := GroupRuleDirection(v.(string)) 123 if rt != GroupRuleIngress && rt != GroupRuleEgress { 124 errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRuleIngress, GroupRuleEgress)) 125 } 126 127 return 128 } 129 130 func validateSecurityRuleIpProtocol(v interface{}, k string) (ws []string, errors []error) { 131 pt := GroupRuleIpProtocol(v.(string)) 132 if pt != GroupRuleTcp && pt != GroupRuleUdp && pt != GroupRuleIcmp && pt != GroupRuleGre && pt != GroupRuleAll { 133 errors = append(errors, fmt.Errorf("%s must be one of %s %s %s %s %s", k, 134 GroupRuleTcp, GroupRuleUdp, GroupRuleIcmp, GroupRuleGre, GroupRuleAll)) 135 } 136 137 return 138 } 139 140 func validateSecurityRuleNicType(v interface{}, k string) (ws []string, errors []error) { 141 pt := GroupRuleNicType(v.(string)) 142 if pt != GroupRuleInternet && pt != GroupRuleIntranet { 143 errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRuleInternet, GroupRuleIntranet)) 144 } 145 146 return 147 } 148 149 func validateSecurityRulePolicy(v interface{}, k string) (ws []string, errors []error) { 150 pt := GroupRulePolicy(v.(string)) 151 if pt != GroupRulePolicyAccept && pt != GroupRulePolicyDrop { 152 errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRulePolicyAccept, GroupRulePolicyDrop)) 153 } 154 155 return 156 } 157 158 func validateSecurityPriority(v interface{}, k string) (ws []string, errors []error) { 159 value := v.(int) 160 if value < 1 || value > 100 { 161 errors = append(errors, fmt.Errorf( 162 "%q must be a valid authorization policy priority between 1 and 100", 163 k)) 164 return 165 } 166 return 167 } 168 169 // validateCIDRNetworkAddress ensures that the string value is a valid CIDR that 170 // represents a network address - it adds an error otherwise 171 func validateCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) { 172 value := v.(string) 173 _, ipnet, err := net.ParseCIDR(value) 174 if err != nil { 175 errors = append(errors, fmt.Errorf( 176 "%q must contain a valid CIDR, got error parsing: %s", k, err)) 177 return 178 } 179 180 if ipnet == nil || value != ipnet.String() { 181 errors = append(errors, fmt.Errorf( 182 "%q must contain a valid network CIDR, expected %q, got %q", 183 k, ipnet, value)) 184 } 185 186 return 187 } 188 189 func validateRouteEntryNextHopType(v interface{}, k string) (ws []string, errors []error) { 190 nht := ecs.NextHopType(v.(string)) 191 if nht != ecs.NextHopIntance && nht != ecs.NextHopTunnel { 192 errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, 193 ecs.NextHopIntance, ecs.NextHopTunnel)) 194 } 195 196 return 197 } 198 199 func validateSwitchCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) { 200 value := v.(string) 201 _, ipnet, err := net.ParseCIDR(value) 202 if err != nil { 203 errors = append(errors, fmt.Errorf( 204 "%q must contain a valid CIDR, got error parsing: %s", k, err)) 205 return 206 } 207 208 if ipnet == nil || value != ipnet.String() { 209 errors = append(errors, fmt.Errorf( 210 "%q must contain a valid network CIDR, expected %q, got %q", 211 k, ipnet, value)) 212 return 213 } 214 215 mark, _ := strconv.Atoi(strings.Split(ipnet.String(), "/")[1]) 216 if mark < 16 || mark > 29 { 217 errors = append(errors, fmt.Errorf( 218 "%q must contain a network CIDR which mark between 16 and 29", 219 k)) 220 } 221 222 return 223 } 224 225 // validateIoOptimized ensures that the string value is a valid IoOptimized that 226 // represents a IoOptimized - it adds an error otherwise 227 func validateIoOptimized(v interface{}, k string) (ws []string, errors []error) { 228 if value := v.(string); value != "" { 229 ioOptimized := ecs.IoOptimized(value) 230 if ioOptimized != ecs.IoOptimizedNone && 231 ioOptimized != ecs.IoOptimizedOptimized { 232 errors = append(errors, fmt.Errorf( 233 "%q must contain a valid IoOptimized, expected %s or %s, got %q", 234 k, ecs.IoOptimizedNone, ecs.IoOptimizedOptimized, ioOptimized)) 235 } 236 } 237 238 return 239 } 240 241 // validateInstanceNetworkType ensures that the string value is a classic or vpc 242 func validateInstanceNetworkType(v interface{}, k string) (ws []string, errors []error) { 243 if value := v.(string); value != "" { 244 network := InstanceNetWork(value) 245 if network != ClassicNet && 246 network != VpcNet { 247 errors = append(errors, fmt.Errorf( 248 "%q must contain a valid InstanceNetworkType, expected %s or %s, go %q", 249 k, ClassicNet, VpcNet, network)) 250 } 251 } 252 return 253 } 254 255 func validateInstanceChargeType(v interface{}, k string) (ws []string, errors []error) { 256 if value := v.(string); value != "" { 257 chargeType := common.InstanceChargeType(value) 258 if chargeType != common.PrePaid && 259 chargeType != common.PostPaid { 260 errors = append(errors, fmt.Errorf( 261 "%q must contain a valid InstanceChargeType, expected %s or %s, got %q", 262 k, common.PrePaid, common.PostPaid, chargeType)) 263 } 264 } 265 266 return 267 } 268 269 func validateInternetChargeType(v interface{}, k string) (ws []string, errors []error) { 270 if value := v.(string); value != "" { 271 chargeType := common.InternetChargeType(value) 272 if chargeType != common.PayByBandwidth && 273 chargeType != common.PayByTraffic { 274 errors = append(errors, fmt.Errorf( 275 "%q must contain a valid InstanceChargeType, expected %s or %s, got %q", 276 k, common.PayByBandwidth, common.PayByTraffic, chargeType)) 277 } 278 } 279 280 return 281 } 282 283 func validateInternetMaxBandWidthOut(v interface{}, k string) (ws []string, errors []error) { 284 value := v.(int) 285 if value < 0 || value > 100 { 286 errors = append(errors, fmt.Errorf( 287 "%q must be a valid internet bandwidth out between 0 and 100", 288 k)) 289 return 290 } 291 return 292 } 293 294 // SLB 295 func validateSlbName(v interface{}, k string) (ws []string, errors []error) { 296 if value := v.(string); value != "" { 297 if len(value) < 1 || len(value) > 80 { 298 errors = append(errors, fmt.Errorf( 299 "%q must be a valid load balancer name characters between 1 and 80", 300 k)) 301 return 302 } 303 } 304 305 return 306 } 307 308 func validateSlbInternetChargeType(v interface{}, k string) (ws []string, errors []error) { 309 if value := v.(string); value != "" { 310 chargeType := common.InternetChargeType(value) 311 312 if chargeType != "paybybandwidth" && 313 chargeType != "paybytraffic" { 314 errors = append(errors, fmt.Errorf( 315 "%q must contain a valid InstanceChargeType, expected %s or %s, got %q", 316 k, "paybybandwidth", "paybytraffic", value)) 317 } 318 } 319 320 return 321 } 322 323 func validateSlbBandwidth(v interface{}, k string) (ws []string, errors []error) { 324 value := v.(int) 325 if value < 1 || value > 1000 { 326 errors = append(errors, fmt.Errorf( 327 "%q must be a valid load balancer bandwidth between 1 and 1000", 328 k)) 329 return 330 } 331 return 332 } 333 334 func validateSlbListenerBandwidth(v interface{}, k string) (ws []string, errors []error) { 335 value := v.(int) 336 if (value < 1 || value > 1000) && value != -1 { 337 errors = append(errors, fmt.Errorf( 338 "%q must be a valid load balancer bandwidth between 1 and 1000 or -1", 339 k)) 340 return 341 } 342 return 343 } 344 345 func validateSlbListenerScheduler(v interface{}, k string) (ws []string, errors []error) { 346 if value := v.(string); value != "" { 347 scheduler := slb.SchedulerType(value) 348 349 if scheduler != "wrr" && scheduler != "wlc" { 350 errors = append(errors, fmt.Errorf( 351 "%q must contain a valid SchedulerType, expected %s or %s, got %q", 352 k, "wrr", "wlc", value)) 353 } 354 } 355 356 return 357 } 358 359 func validateSlbListenerCookie(v interface{}, k string) (ws []string, errors []error) { 360 if value := v.(string); value != "" { 361 if len(value) < 1 || len(value) > 200 { 362 errors = append(errors, fmt.Errorf("%q cannot be longer than 200 characters", k)) 363 } 364 } 365 return 366 } 367 368 func validateSlbListenerCookieTimeout(v interface{}, k string) (ws []string, errors []error) { 369 value := v.(int) 370 if value < 0 || value > 86400 { 371 errors = append(errors, fmt.Errorf( 372 "%q must be a valid load balancer cookie timeout between 0 and 86400", 373 k)) 374 return 375 } 376 return 377 } 378 379 func validateSlbListenerPersistenceTimeout(v interface{}, k string) (ws []string, errors []error) { 380 value := v.(int) 381 if value < 0 || value > 3600 { 382 errors = append(errors, fmt.Errorf( 383 "%q must be a valid load balancer persistence timeout between 0 and 86400", 384 k)) 385 return 386 } 387 return 388 } 389 390 func validateSlbListenerHealthCheckDomain(v interface{}, k string) (ws []string, errors []error) { 391 if value := v.(string); value != "" { 392 //the len add "$_ip",so to max is 84 393 if len(value) < 1 || len(value) > 84 { 394 errors = append(errors, fmt.Errorf("%q cannot be longer than 84 characters", k)) 395 } 396 } 397 return 398 } 399 400 func validateSlbListenerHealthCheckUri(v interface{}, k string) (ws []string, errors []error) { 401 if value := v.(string); value != "" { 402 if len(value) < 1 || len(value) > 80 { 403 errors = append(errors, fmt.Errorf("%q cannot be longer than 80 characters", k)) 404 } 405 } 406 return 407 } 408 409 func validateSlbListenerHealthCheckConnectPort(v interface{}, k string) (ws []string, errors []error) { 410 value := v.(int) 411 if value < 1 || value > 65535 { 412 if value != -520 { 413 errors = append(errors, fmt.Errorf( 414 "%q must be a valid load balancer health check connect port between 1 and 65535 or -520", 415 k)) 416 return 417 } 418 419 } 420 return 421 } 422 423 func validateDBBackupPeriod(v interface{}, k string) (ws []string, errors []error) { 424 days := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} 425 value := v.(string) 426 exist := false 427 for _, d := range days { 428 if value == d { 429 exist = true 430 break 431 } 432 } 433 if !exist { 434 errors = append(errors, fmt.Errorf( 435 "%q must contain a valid backup period value should in array %#v, got %q", 436 k, days, value)) 437 } 438 439 return 440 } 441 442 func validateAllowedStringValue(ss []string) schema.SchemaValidateFunc { 443 return func(v interface{}, k string) (ws []string, errors []error) { 444 value := v.(string) 445 existed := false 446 for _, s := range ss { 447 if s == value { 448 existed = true 449 break 450 } 451 } 452 if !existed { 453 errors = append(errors, fmt.Errorf( 454 "%q must contain a valid string value should in array %#v, got %q", 455 k, ss, value)) 456 } 457 return 458 459 } 460 } 461 462 func validateAllowedSplitStringValue(ss []string, splitStr string) schema.SchemaValidateFunc { 463 return func(v interface{}, k string) (ws []string, errors []error) { 464 value := v.(string) 465 existed := false 466 tsList := strings.Split(value, splitStr) 467 468 for _, ts := range tsList { 469 existed = false 470 for _, s := range ss { 471 if ts == s { 472 existed = true 473 break 474 } 475 } 476 } 477 if !existed { 478 errors = append(errors, fmt.Errorf( 479 "%q must contain a valid string value should in %#v, got %q", 480 k, ss, value)) 481 } 482 return 483 484 } 485 } 486 487 func validateAllowedIntValue(is []int) schema.SchemaValidateFunc { 488 return func(v interface{}, k string) (ws []string, errors []error) { 489 value := v.(int) 490 existed := false 491 for _, i := range is { 492 if i == value { 493 existed = true 494 break 495 } 496 } 497 if !existed { 498 errors = append(errors, fmt.Errorf( 499 "%q must contain a valid int value should in array %#v, got %q", 500 k, is, value)) 501 } 502 return 503 504 } 505 } 506 507 func validateIntegerInRange(min, max int) schema.SchemaValidateFunc { 508 return func(v interface{}, k string) (ws []string, errors []error) { 509 value := v.(int) 510 if value < min { 511 errors = append(errors, fmt.Errorf( 512 "%q cannot be lower than %d: %d", k, min, value)) 513 } 514 if value > max { 515 errors = append(errors, fmt.Errorf( 516 "%q cannot be higher than %d: %d", k, max, value)) 517 } 518 return 519 } 520 } 521 522 //data source validate func 523 //data_source_alicloud_image 524 func validateNameRegex(v interface{}, k string) (ws []string, errors []error) { 525 value := v.(string) 526 527 if _, err := regexp.Compile(value); err != nil { 528 errors = append(errors, fmt.Errorf( 529 "%q contains an invalid regular expression: %s", 530 k, err)) 531 } 532 return 533 } 534 535 func validateImageOwners(v interface{}, k string) (ws []string, errors []error) { 536 if value := v.(string); value != "" { 537 owners := ecs.ImageOwnerAlias(value) 538 if owners != ecs.ImageOwnerSystem && 539 owners != ecs.ImageOwnerSelf && 540 owners != ecs.ImageOwnerOthers && 541 owners != ecs.ImageOwnerMarketplace && 542 owners != ecs.ImageOwnerDefault { 543 errors = append(errors, fmt.Errorf( 544 "%q must contain a valid Image owner , expected %s, %s, %s, %s or %s, got %q", 545 k, ecs.ImageOwnerSystem, ecs.ImageOwnerSelf, ecs.ImageOwnerOthers, ecs.ImageOwnerMarketplace, ecs.ImageOwnerDefault, owners)) 546 } 547 } 548 return 549 } 550 551 func validateRegion(v interface{}, k string) (ws []string, errors []error) { 552 if value := v.(string); value != "" { 553 region := common.Region(value) 554 var valid string 555 for _, re := range common.ValidRegions { 556 if region == re { 557 return 558 } 559 valid = valid + ", " + string(re) 560 } 561 errors = append(errors, fmt.Errorf( 562 "%q must contain a valid Region ID , expected %#v, got %q", 563 k, valid, value)) 564 565 } 566 return 567 } 568 569 func validateForwardPort(v interface{}, k string) (ws []string, errors []error) { 570 value := v.(string) 571 if value != "any" { 572 valueConv, err := strconv.Atoi(value) 573 if err != nil || valueConv < 1 || valueConv > 65535 { 574 errors = append(errors, fmt.Errorf("%q must be a valid port between 1 and 65535 or any ", k)) 575 } 576 } 577 return 578 }