github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/aws/validators_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/service/s3" 9 ) 10 11 func TestValidateEcrRepositoryName(t *testing.T) { 12 validNames := []string{ 13 "nginx-web-app", 14 "project-a/nginx-web-app", 15 "domain.ltd/nginx-web-app", 16 "3chosome-thing.com/01different-pattern", 17 "0123456789/999999999", 18 "double/forward/slash", 19 "000000000000000", 20 } 21 for _, v := range validNames { 22 _, errors := validateEcrRepositoryName(v, "name") 23 if len(errors) != 0 { 24 t.Fatalf("%q should be a valid ECR repository name: %q", v, errors) 25 } 26 } 27 28 invalidNames := []string{ 29 // length > 256 30 "3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" + 31 "erent.-_pattern01different.-_pattern01different.-_pattern01different" + 32 ".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" + 33 "ttern01different.-_pattern01different.-_pattern234567", 34 // length < 2 35 "i", 36 "special@character", 37 "different+special=character", 38 "double//slash", 39 "double..dot", 40 "/slash-at-the-beginning", 41 "slash-at-the-end/", 42 } 43 for _, v := range invalidNames { 44 _, errors := validateEcrRepositoryName(v, "name") 45 if len(errors) == 0 { 46 t.Fatalf("%q should be an invalid ECR repository name", v) 47 } 48 } 49 } 50 51 func TestValidateCloudWatchEventRuleName(t *testing.T) { 52 validNames := []string{ 53 "HelloWorl_d", 54 "hello-world", 55 "hello.World0125", 56 } 57 for _, v := range validNames { 58 _, errors := validateCloudWatchEventRuleName(v, "name") 59 if len(errors) != 0 { 60 t.Fatalf("%q should be a valid CW event rule name: %q", v, errors) 61 } 62 } 63 64 invalidNames := []string{ 65 "special@character", 66 "slash/in-the-middle", 67 // Length > 64 68 "TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName", 69 } 70 for _, v := range invalidNames { 71 _, errors := validateCloudWatchEventRuleName(v, "name") 72 if len(errors) == 0 { 73 t.Fatalf("%q should be an invalid CW event rule name", v) 74 } 75 } 76 } 77 78 func TestValidateLambdaFunctionName(t *testing.T) { 79 validNames := []string{ 80 "arn:aws:lambda:us-west-2:123456789012:function:ThumbNail", 81 "arn:aws-us-gov:lambda:us-west-2:123456789012:function:ThumbNail", 82 "FunctionName", 83 "function-name", 84 } 85 for _, v := range validNames { 86 _, errors := validateLambdaFunctionName(v, "name") 87 if len(errors) != 0 { 88 t.Fatalf("%q should be a valid Lambda function name: %q", v, errors) 89 } 90 } 91 92 invalidNames := []string{ 93 "/FunctionNameWithSlash", 94 "function.name.with.dots", 95 // length > 140 96 "arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" + 97 "ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" + 98 "ooooooooooooooooongFunctionName", 99 } 100 for _, v := range invalidNames { 101 _, errors := validateLambdaFunctionName(v, "name") 102 if len(errors) == 0 { 103 t.Fatalf("%q should be an invalid Lambda function name", v) 104 } 105 } 106 } 107 108 func TestValidateLambdaQualifier(t *testing.T) { 109 validNames := []string{ 110 "123", 111 "prod", 112 "PROD", 113 "MyTestEnv", 114 "contains-dashes", 115 "contains_underscores", 116 "$LATEST", 117 } 118 for _, v := range validNames { 119 _, errors := validateLambdaQualifier(v, "name") 120 if len(errors) != 0 { 121 t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors) 122 } 123 } 124 125 invalidNames := []string{ 126 // No ARNs allowed 127 "arn:aws:lambda:us-west-2:123456789012:function:prod", 128 // length > 128 129 "TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" + 130 "ooooooooooooooooooooooooooooooooooooooooooooooooooo" + 131 "oooooooooooongQualifier", 132 } 133 for _, v := range invalidNames { 134 _, errors := validateLambdaQualifier(v, "name") 135 if len(errors) == 0 { 136 t.Fatalf("%q should be an invalid Lambda function qualifier", v) 137 } 138 } 139 } 140 141 func TestValidateLambdaPermissionAction(t *testing.T) { 142 validNames := []string{ 143 "lambda:*", 144 "lambda:InvokeFunction", 145 "*", 146 } 147 for _, v := range validNames { 148 _, errors := validateLambdaPermissionAction(v, "action") 149 if len(errors) != 0 { 150 t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors) 151 } 152 } 153 154 invalidNames := []string{ 155 "yada", 156 "lambda:123", 157 "*:*", 158 "lambda:Invoke*", 159 } 160 for _, v := range invalidNames { 161 _, errors := validateLambdaPermissionAction(v, "action") 162 if len(errors) == 0 { 163 t.Fatalf("%q should be an invalid Lambda permission action", v) 164 } 165 } 166 } 167 168 func TestValidateAwsAccountId(t *testing.T) { 169 validNames := []string{ 170 "123456789012", 171 "999999999999", 172 } 173 for _, v := range validNames { 174 _, errors := validateAwsAccountId(v, "account_id") 175 if len(errors) != 0 { 176 t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors) 177 } 178 } 179 180 invalidNames := []string{ 181 "12345678901", // too short 182 "1234567890123", // too long 183 "invalid", 184 "x123456789012", 185 } 186 for _, v := range invalidNames { 187 _, errors := validateAwsAccountId(v, "account_id") 188 if len(errors) == 0 { 189 t.Fatalf("%q should be an invalid AWS Account ID", v) 190 } 191 } 192 } 193 194 func TestValidateArn(t *testing.T) { 195 v := "" 196 _, errors := validateArn(v, "arn") 197 if len(errors) != 0 { 198 t.Fatalf("%q should not be validated as an ARN: %q", v, errors) 199 } 200 201 validNames := []string{ 202 "arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk 203 "arn:aws:iam::123456789012:user/David", // IAM User 204 "arn:aws:rds:eu-west-1:123456789012:db:mysql-db", // RDS 205 "arn:aws:s3:::my_corporate_bucket/exampleobject.png", // S3 object 206 "arn:aws:events:us-east-1:319201112229:rule/rule_name", // CloudWatch Rule 207 "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction", // Lambda function 208 "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier", // Lambda func qualifier 209 "arn:aws-us-gov:s3:::corp_bucket/object.png", // GovCloud ARN 210 "arn:aws-us-gov:kms:us-gov-west-1:123456789012:key/some-uuid-abc123", // GovCloud KMS ARN 211 } 212 for _, v := range validNames { 213 _, errors := validateArn(v, "arn") 214 if len(errors) != 0 { 215 t.Fatalf("%q should be a valid ARN: %q", v, errors) 216 } 217 } 218 219 invalidNames := []string{ 220 "arn", 221 "123456789012", 222 "arn:aws", 223 "arn:aws:logs", 224 "arn:aws:logs:region:*:*", 225 } 226 for _, v := range invalidNames { 227 _, errors := validateArn(v, "arn") 228 if len(errors) == 0 { 229 t.Fatalf("%q should be an invalid ARN", v) 230 } 231 } 232 } 233 234 func TestValidatePolicyStatementId(t *testing.T) { 235 validNames := []string{ 236 "YadaHereAndThere", 237 "Valid-5tatement_Id", 238 "1234", 239 } 240 for _, v := range validNames { 241 _, errors := validatePolicyStatementId(v, "statement_id") 242 if len(errors) != 0 { 243 t.Fatalf("%q should be a valid Statement ID: %q", v, errors) 244 } 245 } 246 247 invalidNames := []string{ 248 "Invalid/StatementId/with/slashes", 249 "InvalidStatementId.with.dots", 250 // length > 100 251 "TooooLoooooooooooooooooooooooooooooooooooooooooooo" + 252 "ooooooooooooooooooooooooooooooooooooooooStatementId", 253 } 254 for _, v := range invalidNames { 255 _, errors := validatePolicyStatementId(v, "statement_id") 256 if len(errors) == 0 { 257 t.Fatalf("%q should be an invalid Statement ID", v) 258 } 259 } 260 } 261 262 func TestValidateCIDRNetworkAddress(t *testing.T) { 263 cases := []struct { 264 CIDR string 265 ExpectedErrSubstr string 266 }{ 267 {"notacidr", `must contain a valid CIDR`}, 268 {"10.0.1.0/16", `must contain a valid network CIDR`}, 269 {"10.0.1.0/24", ``}, 270 } 271 272 for i, tc := range cases { 273 _, errs := validateCIDRNetworkAddress(tc.CIDR, "foo") 274 if tc.ExpectedErrSubstr == "" { 275 if len(errs) != 0 { 276 t.Fatalf("%d/%d: Expected no error, got errs: %#v", 277 i+1, len(cases), errs) 278 } 279 } else { 280 if len(errs) != 1 { 281 t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs", 282 i+1, len(cases), tc.ExpectedErrSubstr, len(errs)) 283 } 284 if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) { 285 t.Fatalf("%d/%d: Expected err: %q, to include %q", 286 i+1, len(cases), errs[0], tc.ExpectedErrSubstr) 287 } 288 } 289 } 290 } 291 292 func TestValidateHTTPMethod(t *testing.T) { 293 type testCases struct { 294 Value string 295 ErrCount int 296 } 297 298 invalidCases := []testCases{ 299 { 300 Value: "incorrect", 301 ErrCount: 1, 302 }, 303 { 304 Value: "delete", 305 ErrCount: 1, 306 }, 307 } 308 309 for _, tc := range invalidCases { 310 _, errors := validateHTTPMethod(tc.Value, "http_method") 311 if len(errors) != tc.ErrCount { 312 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 313 } 314 } 315 316 validCases := []testCases{ 317 { 318 Value: "ANY", 319 ErrCount: 0, 320 }, 321 { 322 Value: "DELETE", 323 ErrCount: 0, 324 }, 325 { 326 Value: "OPTIONS", 327 ErrCount: 0, 328 }, 329 } 330 331 for _, tc := range validCases { 332 _, errors := validateHTTPMethod(tc.Value, "http_method") 333 if len(errors) != tc.ErrCount { 334 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 335 } 336 } 337 } 338 339 func TestValidateLogMetricFilterName(t *testing.T) { 340 validNames := []string{ 341 "YadaHereAndThere", 342 "Valid-5Metric_Name", 343 "This . is also %% valid@!)+(", 344 "1234", 345 strings.Repeat("W", 512), 346 } 347 for _, v := range validNames { 348 _, errors := validateLogMetricFilterName(v, "name") 349 if len(errors) != 0 { 350 t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors) 351 } 352 } 353 354 invalidNames := []string{ 355 "Here is a name with: colon", 356 "and here is another * invalid name", 357 "*", 358 // length > 512 359 strings.Repeat("W", 513), 360 } 361 for _, v := range invalidNames { 362 _, errors := validateLogMetricFilterName(v, "name") 363 if len(errors) == 0 { 364 t.Fatalf("%q should be an invalid Log Metric Filter Name", v) 365 } 366 } 367 } 368 369 func TestValidateLogMetricTransformationName(t *testing.T) { 370 validNames := []string{ 371 "YadaHereAndThere", 372 "Valid-5Metric_Name", 373 "This . is also %% valid@!)+(", 374 "1234", 375 "", 376 strings.Repeat("W", 255), 377 } 378 for _, v := range validNames { 379 _, errors := validateLogMetricFilterTransformationName(v, "name") 380 if len(errors) != 0 { 381 t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors) 382 } 383 } 384 385 invalidNames := []string{ 386 "Here is a name with: colon", 387 "and here is another * invalid name", 388 "also $ invalid", 389 "*", 390 // length > 255 391 strings.Repeat("W", 256), 392 } 393 for _, v := range invalidNames { 394 _, errors := validateLogMetricFilterTransformationName(v, "name") 395 if len(errors) == 0 { 396 t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v) 397 } 398 } 399 } 400 401 func TestValidateLogGroupName(t *testing.T) { 402 validNames := []string{ 403 "ValidLogGroupName", 404 "ValidLogGroup.Name", 405 "valid/Log-group", 406 "1234", 407 "YadaValid#0123", 408 "Also_valid-name", 409 strings.Repeat("W", 512), 410 } 411 for _, v := range validNames { 412 _, errors := validateLogGroupName(v, "name") 413 if len(errors) != 0 { 414 t.Fatalf("%q should be a valid Log Group name: %q", v, errors) 415 } 416 } 417 418 invalidNames := []string{ 419 "Here is a name with: colon", 420 "and here is another * invalid name", 421 "also $ invalid", 422 "This . is also %% invalid@!)+(", 423 "*", 424 "", 425 // length > 512 426 strings.Repeat("W", 513), 427 } 428 for _, v := range invalidNames { 429 _, errors := validateLogGroupName(v, "name") 430 if len(errors) == 0 { 431 t.Fatalf("%q should be an invalid Log Group name", v) 432 } 433 } 434 } 435 436 func TestValidateLogGroupNamePrefix(t *testing.T) { 437 validNames := []string{ 438 "ValidLogGroupName", 439 "ValidLogGroup.Name", 440 "valid/Log-group", 441 "1234", 442 "YadaValid#0123", 443 "Also_valid-name", 444 strings.Repeat("W", 483), 445 } 446 for _, v := range validNames { 447 _, errors := validateLogGroupNamePrefix(v, "name_prefix") 448 if len(errors) != 0 { 449 t.Fatalf("%q should be a valid Log Group name prefix: %q", v, errors) 450 } 451 } 452 453 invalidNames := []string{ 454 "Here is a name with: colon", 455 "and here is another * invalid name", 456 "also $ invalid", 457 "This . is also %% invalid@!)+(", 458 "*", 459 "", 460 // length > 483 461 strings.Repeat("W", 484), 462 } 463 for _, v := range invalidNames { 464 _, errors := validateLogGroupNamePrefix(v, "name_prefix") 465 if len(errors) == 0 { 466 t.Fatalf("%q should be an invalid Log Group name prefix", v) 467 } 468 } 469 } 470 471 func TestValidateS3BucketLifecycleTimestamp(t *testing.T) { 472 validDates := []string{ 473 "2016-01-01", 474 "2006-01-02", 475 } 476 477 for _, v := range validDates { 478 _, errors := validateS3BucketLifecycleTimestamp(v, "date") 479 if len(errors) != 0 { 480 t.Fatalf("%q should be valid date: %q", v, errors) 481 } 482 } 483 484 invalidDates := []string{ 485 "Jan 01 2016", 486 "20160101", 487 } 488 489 for _, v := range invalidDates { 490 _, errors := validateS3BucketLifecycleTimestamp(v, "date") 491 if len(errors) == 0 { 492 t.Fatalf("%q should be invalid date", v) 493 } 494 } 495 } 496 497 func TestValidateS3BucketLifecycleStorageClass(t *testing.T) { 498 validStorageClass := []string{ 499 "STANDARD_IA", 500 "GLACIER", 501 } 502 503 for _, v := range validStorageClass { 504 _, errors := validateS3BucketLifecycleStorageClass(v, "storage_class") 505 if len(errors) != 0 { 506 t.Fatalf("%q should be valid storage class: %q", v, errors) 507 } 508 } 509 510 invalidStorageClass := []string{ 511 "STANDARD", 512 "1234", 513 } 514 for _, v := range invalidStorageClass { 515 _, errors := validateS3BucketLifecycleStorageClass(v, "storage_class") 516 if len(errors) == 0 { 517 t.Fatalf("%q should be invalid storage class", v) 518 } 519 } 520 } 521 522 func TestValidateS3BucketReplicationRuleId(t *testing.T) { 523 validId := []string{ 524 "YadaHereAndThere", 525 "Valid-5Rule_ID", 526 "This . is also %% valid@!)+*(:ID", 527 "1234", 528 strings.Repeat("W", 255), 529 } 530 for _, v := range validId { 531 _, errors := validateS3BucketReplicationRuleId(v, "id") 532 if len(errors) != 0 { 533 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 534 } 535 } 536 537 invalidId := []string{ 538 // length > 255 539 strings.Repeat("W", 256), 540 } 541 for _, v := range invalidId { 542 _, errors := validateS3BucketReplicationRuleId(v, "id") 543 if len(errors) == 0 { 544 t.Fatalf("%q should be an invalid replication configuration rule id", v) 545 } 546 } 547 } 548 549 func TestValidateS3BucketReplicationRulePrefix(t *testing.T) { 550 validId := []string{ 551 "YadaHereAndThere", 552 "Valid-5Rule_ID", 553 "This . is also %% valid@!)+*(:ID", 554 "1234", 555 strings.Repeat("W", 1024), 556 } 557 for _, v := range validId { 558 _, errors := validateS3BucketReplicationRulePrefix(v, "id") 559 if len(errors) != 0 { 560 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 561 } 562 } 563 564 invalidId := []string{ 565 // length > 1024 566 strings.Repeat("W", 1025), 567 } 568 for _, v := range invalidId { 569 _, errors := validateS3BucketReplicationRulePrefix(v, "id") 570 if len(errors) == 0 { 571 t.Fatalf("%q should be an invalid replication configuration rule id", v) 572 } 573 } 574 } 575 576 func TestValidateS3BucketReplicationDestinationStorageClass(t *testing.T) { 577 validStorageClass := []string{ 578 s3.StorageClassStandard, 579 s3.StorageClassStandardIa, 580 s3.StorageClassReducedRedundancy, 581 } 582 583 for _, v := range validStorageClass { 584 _, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class") 585 if len(errors) != 0 { 586 t.Fatalf("%q should be valid storage class: %q", v, errors) 587 } 588 } 589 590 invalidStorageClass := []string{ 591 "FOO", 592 "1234", 593 } 594 for _, v := range invalidStorageClass { 595 _, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class") 596 if len(errors) == 0 { 597 t.Fatalf("%q should be invalid storage class", v) 598 } 599 } 600 } 601 602 func TestValidateS3BucketReplicationRuleStatus(t *testing.T) { 603 validRuleStatuses := []string{ 604 s3.ReplicationRuleStatusEnabled, 605 s3.ReplicationRuleStatusDisabled, 606 } 607 608 for _, v := range validRuleStatuses { 609 _, errors := validateS3BucketReplicationRuleStatus(v, "status") 610 if len(errors) != 0 { 611 t.Fatalf("%q should be valid rule status: %q", v, errors) 612 } 613 } 614 615 invalidRuleStatuses := []string{ 616 "FOO", 617 "1234", 618 } 619 for _, v := range invalidRuleStatuses { 620 _, errors := validateS3BucketReplicationRuleStatus(v, "status") 621 if len(errors) == 0 { 622 t.Fatalf("%q should be invalid rule status", v) 623 } 624 } 625 } 626 627 func TestValidateS3BucketLifecycleRuleId(t *testing.T) { 628 validId := []string{ 629 "YadaHereAndThere", 630 "Valid-5Rule_ID", 631 "This . is also %% valid@!)+*(:ID", 632 "1234", 633 strings.Repeat("W", 255), 634 } 635 for _, v := range validId { 636 _, errors := validateS3BucketLifecycleRuleId(v, "id") 637 if len(errors) != 0 { 638 t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors) 639 } 640 } 641 642 invalidId := []string{ 643 // length > 255 644 strings.Repeat("W", 256), 645 } 646 for _, v := range invalidId { 647 _, errors := validateS3BucketLifecycleRuleId(v, "id") 648 if len(errors) == 0 { 649 t.Fatalf("%q should be an invalid lifecycle rule id", v) 650 } 651 } 652 } 653 654 func TestValidateIntegerInRange(t *testing.T) { 655 validIntegers := []int{-259, 0, 1, 5, 999} 656 min := -259 657 max := 999 658 for _, v := range validIntegers { 659 _, errors := validateIntegerInRange(min, max)(v, "name") 660 if len(errors) != 0 { 661 t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors) 662 } 663 } 664 665 invalidIntegers := []int{-260, -99999, 1000, 25678} 666 for _, v := range invalidIntegers { 667 _, errors := validateIntegerInRange(min, max)(v, "name") 668 if len(errors) == 0 { 669 t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max) 670 } 671 } 672 } 673 674 func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) { 675 cases := []struct { 676 Value string 677 ErrCount int 678 }{ 679 { 680 Value: "tEsting", 681 ErrCount: 1, 682 }, 683 { 684 Value: "t.sting", 685 ErrCount: 1, 686 }, 687 { 688 Value: "t--sting", 689 ErrCount: 1, 690 }, 691 { 692 Value: "1testing", 693 ErrCount: 1, 694 }, 695 { 696 Value: "testing-", 697 ErrCount: 1, 698 }, 699 { 700 Value: randomString(65), 701 ErrCount: 1, 702 }, 703 } 704 705 for _, tc := range cases { 706 _, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id") 707 708 if len(errors) != tc.ErrCount { 709 t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error") 710 } 711 } 712 } 713 714 func TestValidateDbEventSubscriptionName(t *testing.T) { 715 validNames := []string{ 716 "valid-name", 717 "valid02-name", 718 "Valid-Name1", 719 } 720 for _, v := range validNames { 721 _, errors := validateDbEventSubscriptionName(v, "name") 722 if len(errors) != 0 { 723 t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors) 724 } 725 } 726 727 invalidNames := []string{ 728 "Here is a name with: colon", 729 "and here is another * invalid name", 730 "also $ invalid", 731 "This . is also %% invalid@!)+(", 732 "*", 733 "", 734 " ", 735 "_", 736 // length > 255 737 strings.Repeat("W", 256), 738 } 739 for _, v := range invalidNames { 740 _, errors := validateDbEventSubscriptionName(v, "name") 741 if len(errors) == 0 { 742 t.Fatalf("%q should be an invalid RDS Event Subscription Name", v) 743 } 744 } 745 } 746 747 func TestValidateJsonString(t *testing.T) { 748 type testCases struct { 749 Value string 750 ErrCount int 751 } 752 753 invalidCases := []testCases{ 754 { 755 Value: `{0:"1"}`, 756 ErrCount: 1, 757 }, 758 { 759 Value: `{'abc':1}`, 760 ErrCount: 1, 761 }, 762 { 763 Value: `{"def":}`, 764 ErrCount: 1, 765 }, 766 { 767 Value: `{"xyz":[}}`, 768 ErrCount: 1, 769 }, 770 } 771 772 for _, tc := range invalidCases { 773 _, errors := validateJsonString(tc.Value, "json") 774 if len(errors) != tc.ErrCount { 775 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 776 } 777 } 778 779 validCases := []testCases{ 780 { 781 Value: ``, 782 ErrCount: 0, 783 }, 784 { 785 Value: `{}`, 786 ErrCount: 0, 787 }, 788 { 789 Value: `{"abc":["1","2"]}`, 790 ErrCount: 0, 791 }, 792 } 793 794 for _, tc := range validCases { 795 _, errors := validateJsonString(tc.Value, "json") 796 if len(errors) != tc.ErrCount { 797 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 798 } 799 } 800 } 801 802 func TestValidateIAMPolicyJsonString(t *testing.T) { 803 type testCases struct { 804 Value string 805 ErrCount int 806 } 807 808 invalidCases := []testCases{ 809 { 810 Value: `{0:"1"}`, 811 ErrCount: 1, 812 }, 813 { 814 Value: `{'abc':1}`, 815 ErrCount: 1, 816 }, 817 { 818 Value: `{"def":}`, 819 ErrCount: 1, 820 }, 821 { 822 Value: `{"xyz":[}}`, 823 ErrCount: 1, 824 }, 825 { 826 Value: ``, 827 ErrCount: 1, 828 }, 829 { 830 Value: ` {"xyz": "foo"}`, 831 ErrCount: 1, 832 }, 833 } 834 835 for _, tc := range invalidCases { 836 _, errors := validateIAMPolicyJson(tc.Value, "json") 837 if len(errors) != tc.ErrCount { 838 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 839 } 840 } 841 842 validCases := []testCases{ 843 { 844 Value: `{}`, 845 ErrCount: 0, 846 }, 847 { 848 Value: `{"abc":["1","2"]}`, 849 ErrCount: 0, 850 }, 851 } 852 853 for _, tc := range validCases { 854 _, errors := validateIAMPolicyJson(tc.Value, "json") 855 if len(errors) != tc.ErrCount { 856 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 857 } 858 } 859 } 860 861 func TestValidateCloudFormationTemplate(t *testing.T) { 862 type testCases struct { 863 Value string 864 ErrCount int 865 } 866 867 invalidCases := []testCases{ 868 { 869 Value: `{"abc":"`, 870 ErrCount: 1, 871 }, 872 { 873 Value: "abc: [", 874 ErrCount: 1, 875 }, 876 } 877 878 for _, tc := range invalidCases { 879 _, errors := validateCloudFormationTemplate(tc.Value, "template") 880 if len(errors) != tc.ErrCount { 881 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 882 } 883 } 884 885 validCases := []testCases{ 886 { 887 Value: `{"abc":"1"}`, 888 ErrCount: 0, 889 }, 890 { 891 Value: `abc: 1`, 892 ErrCount: 0, 893 }, 894 } 895 896 for _, tc := range validCases { 897 _, errors := validateCloudFormationTemplate(tc.Value, "template") 898 if len(errors) != tc.ErrCount { 899 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 900 } 901 } 902 } 903 904 func TestValidateApiGatewayIntegrationType(t *testing.T) { 905 type testCases struct { 906 Value string 907 ErrCount int 908 } 909 910 invalidCases := []testCases{ 911 { 912 Value: "incorrect", 913 ErrCount: 1, 914 }, 915 { 916 Value: "aws_proxy", 917 ErrCount: 1, 918 }, 919 } 920 921 for _, tc := range invalidCases { 922 _, errors := validateApiGatewayIntegrationType(tc.Value, "types") 923 if len(errors) != tc.ErrCount { 924 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 925 } 926 } 927 928 validCases := []testCases{ 929 { 930 Value: "MOCK", 931 ErrCount: 0, 932 }, 933 { 934 Value: "AWS_PROXY", 935 ErrCount: 0, 936 }, 937 } 938 939 for _, tc := range validCases { 940 _, errors := validateApiGatewayIntegrationType(tc.Value, "types") 941 if len(errors) != tc.ErrCount { 942 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 943 } 944 } 945 } 946 947 func TestValidateSQSQueueName(t *testing.T) { 948 validNames := []string{ 949 "valid-name", 950 "valid02-name", 951 "Valid-Name1", 952 "_", 953 "-", 954 strings.Repeat("W", 80), 955 } 956 for _, v := range validNames { 957 if errors := validateSQSQueueName(v, "name"); len(errors) > 0 { 958 t.Fatalf("%q should be a valid SQS queue Name", v) 959 } 960 } 961 962 invalidNames := []string{ 963 "Here is a name with: colon", 964 "another * invalid name", 965 "also $ invalid", 966 "This . is also %% invalid@!)+(", 967 "*", 968 "", 969 " ", 970 ".", 971 strings.Repeat("W", 81), // length > 80 972 } 973 for _, v := range invalidNames { 974 if errors := validateSQSQueueName(v, "name"); len(errors) == 0 { 975 t.Fatalf("%q should be an invalid SQS queue Name", v) 976 } 977 } 978 } 979 980 func TestValidateSQSFifoQueueName(t *testing.T) { 981 validNames := []string{ 982 "valid-name.fifo", 983 "valid02-name.fifo", 984 "Valid-Name1.fifo", 985 "_.fifo", 986 "a.fifo", 987 "A.fifo", 988 "9.fifo", 989 "-.fifo", 990 fmt.Sprintf("%s.fifo", strings.Repeat("W", 75)), 991 } 992 for _, v := range validNames { 993 if errors := validateSQSFifoQueueName(v, "name"); len(errors) > 0 { 994 t.Fatalf("%q should be a valid SQS FIFO queue Name: %v", v, errors) 995 } 996 } 997 998 invalidNames := []string{ 999 "Here is a name with: colon", 1000 "another * invalid name", 1001 "also $ invalid", 1002 "This . is also %% invalid@!)+(", 1003 ".fifo", 1004 "*", 1005 "", 1006 " ", 1007 ".", 1008 strings.Repeat("W", 81), // length > 80 1009 } 1010 for _, v := range invalidNames { 1011 if errors := validateSQSFifoQueueName(v, "name"); len(errors) == 0 { 1012 t.Fatalf("%q should be an invalid SQS FIFO queue Name: %v", v, errors) 1013 } 1014 } 1015 } 1016 1017 func TestValidateSNSSubscriptionProtocol(t *testing.T) { 1018 validProtocols := []string{ 1019 "lambda", 1020 "sqs", 1021 "sqs", 1022 "application", 1023 "http", 1024 "https", 1025 } 1026 for _, v := range validProtocols { 1027 if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) > 0 { 1028 t.Fatalf("%q should be a valid SNS Subscription protocol: %v", v, errors) 1029 } 1030 } 1031 1032 invalidProtocols := []string{ 1033 "Email", 1034 "email", 1035 "Email-JSON", 1036 "email-json", 1037 "SMS", 1038 "sms", 1039 } 1040 for _, v := range invalidProtocols { 1041 if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) == 0 { 1042 t.Fatalf("%q should be an invalid SNS Subscription protocol: %v", v, errors) 1043 } 1044 } 1045 } 1046 1047 func TestValidateSecurityRuleType(t *testing.T) { 1048 validTypes := []string{ 1049 "ingress", 1050 "egress", 1051 } 1052 for _, v := range validTypes { 1053 if _, errors := validateSecurityRuleType(v, "type"); len(errors) > 0 { 1054 t.Fatalf("%q should be a valid Security Group Rule type: %v", v, errors) 1055 } 1056 } 1057 1058 invalidTypes := []string{ 1059 "foo", 1060 "ingresss", 1061 } 1062 for _, v := range invalidTypes { 1063 if _, errors := validateSecurityRuleType(v, "type"); len(errors) == 0 { 1064 t.Fatalf("%q should be an invalid Security Group Rule type: %v", v, errors) 1065 } 1066 } 1067 } 1068 1069 func TestValidateOnceAWeekWindowFormat(t *testing.T) { 1070 cases := []struct { 1071 Value string 1072 ErrCount int 1073 }{ 1074 { 1075 // once a day window format 1076 Value: "04:00-05:00", 1077 ErrCount: 1, 1078 }, 1079 { 1080 // invalid day of week 1081 Value: "san:04:00-san:05:00", 1082 ErrCount: 1, 1083 }, 1084 { 1085 // invalid hour 1086 Value: "sun:24:00-san:25:00", 1087 ErrCount: 1, 1088 }, 1089 { 1090 // invalid min 1091 Value: "sun:04:00-sun:04:60", 1092 ErrCount: 1, 1093 }, 1094 { 1095 // valid format 1096 Value: "sun:04:00-sun:05:00", 1097 ErrCount: 0, 1098 }, 1099 { 1100 // "Sun" can also be used 1101 Value: "Sun:04:00-Sun:05:00", 1102 ErrCount: 0, 1103 }, 1104 { 1105 // valid format 1106 Value: "", 1107 ErrCount: 0, 1108 }, 1109 } 1110 1111 for _, tc := range cases { 1112 _, errors := validateOnceAWeekWindowFormat(tc.Value, "maintenance_window") 1113 1114 if len(errors) != tc.ErrCount { 1115 t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) 1116 } 1117 } 1118 } 1119 1120 func TestValidateOnceADayWindowFormat(t *testing.T) { 1121 cases := []struct { 1122 Value string 1123 ErrCount int 1124 }{ 1125 { 1126 // once a week window format 1127 Value: "sun:04:00-sun:05:00", 1128 ErrCount: 1, 1129 }, 1130 { 1131 // invalid hour 1132 Value: "24:00-25:00", 1133 ErrCount: 1, 1134 }, 1135 { 1136 // invalid min 1137 Value: "04:00-04:60", 1138 ErrCount: 1, 1139 }, 1140 { 1141 // valid format 1142 Value: "04:00-05:00", 1143 ErrCount: 0, 1144 }, 1145 { 1146 // valid format 1147 Value: "", 1148 ErrCount: 0, 1149 }, 1150 } 1151 1152 for _, tc := range cases { 1153 _, errors := validateOnceADayWindowFormat(tc.Value, "backup_window") 1154 1155 if len(errors) != tc.ErrCount { 1156 t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value) 1157 } 1158 } 1159 } 1160 1161 func TestValidateRoute53RecordType(t *testing.T) { 1162 validTypes := []string{ 1163 "AAAA", 1164 "SOA", 1165 "A", 1166 "TXT", 1167 "CNAME", 1168 "MX", 1169 "NAPTR", 1170 "PTR", 1171 "SPF", 1172 "SRV", 1173 "NS", 1174 } 1175 1176 invalidTypes := []string{ 1177 "a", 1178 "alias", 1179 "SpF", 1180 "Txt", 1181 "AaAA", 1182 } 1183 1184 for _, v := range validTypes { 1185 _, errors := validateRoute53RecordType(v, "route53_record") 1186 if len(errors) != 0 { 1187 t.Fatalf("%q should be a valid Route53 record type: %v", v, errors) 1188 } 1189 } 1190 1191 for _, v := range invalidTypes { 1192 _, errors := validateRoute53RecordType(v, "route53_record") 1193 if len(errors) == 0 { 1194 t.Fatalf("%q should not be a valid Route53 record type", v) 1195 } 1196 } 1197 } 1198 1199 func TestValidateEcsPlacementConstraint(t *testing.T) { 1200 cases := []struct { 1201 constType string 1202 constExpr string 1203 Err bool 1204 }{ 1205 { 1206 constType: "distinctInstance", 1207 constExpr: "", 1208 Err: false, 1209 }, 1210 { 1211 constType: "memberOf", 1212 constExpr: "", 1213 Err: true, 1214 }, 1215 { 1216 constType: "distinctInstance", 1217 constExpr: "expression", 1218 Err: false, 1219 }, 1220 { 1221 constType: "memberOf", 1222 constExpr: "expression", 1223 Err: false, 1224 }, 1225 } 1226 1227 for _, tc := range cases { 1228 if err := validateAwsEcsPlacementConstraint(tc.constType, tc.constExpr); err != nil && !tc.Err { 1229 t.Fatalf("Unexpected validation error for \"%s:%s\": %s", 1230 tc.constType, tc.constExpr, err) 1231 } 1232 1233 } 1234 } 1235 1236 func TestValidateEcsPlacementStrategy(t *testing.T) { 1237 cases := []struct { 1238 stratType string 1239 stratField string 1240 Err bool 1241 }{ 1242 { 1243 stratType: "random", 1244 stratField: "", 1245 Err: false, 1246 }, 1247 { 1248 stratType: "spread", 1249 stratField: "instanceID", 1250 Err: false, 1251 }, 1252 { 1253 stratType: "binpack", 1254 stratField: "cpu", 1255 Err: false, 1256 }, 1257 { 1258 stratType: "binpack", 1259 stratField: "memory", 1260 Err: false, 1261 }, 1262 { 1263 stratType: "binpack", 1264 stratField: "disk", 1265 Err: true, 1266 }, 1267 { 1268 stratType: "fakeType", 1269 stratField: "", 1270 Err: true, 1271 }, 1272 } 1273 1274 for _, tc := range cases { 1275 if err := validateAwsEcsPlacementStrategy(tc.stratType, tc.stratField); err != nil && !tc.Err { 1276 t.Fatalf("Unexpected validation error for \"%s:%s\": %s", 1277 tc.stratType, tc.stratField, err) 1278 } 1279 } 1280 } 1281 1282 func TestValidateStepFunctionActivityName(t *testing.T) { 1283 validTypes := []string{ 1284 "foo", 1285 "FooBar123", 1286 } 1287 1288 invalidTypes := []string{ 1289 strings.Repeat("W", 81), // length > 80 1290 } 1291 1292 for _, v := range validTypes { 1293 _, errors := validateSfnActivityName(v, "name") 1294 if len(errors) != 0 { 1295 t.Fatalf("%q should be a valid Step Function Activity name: %v", v, errors) 1296 } 1297 } 1298 1299 for _, v := range invalidTypes { 1300 _, errors := validateSfnActivityName(v, "name") 1301 if len(errors) == 0 { 1302 t.Fatalf("%q should not be a valid Step Function Activity name", v) 1303 } 1304 } 1305 } 1306 1307 func TestValidateStepFunctionStateMachineDefinition(t *testing.T) { 1308 validDefinitions := []string{ 1309 "foobar", 1310 strings.Repeat("W", 1048576), 1311 } 1312 1313 invalidDefinitions := []string{ 1314 strings.Repeat("W", 1048577), // length > 1048576 1315 } 1316 1317 for _, v := range validDefinitions { 1318 _, errors := validateSfnStateMachineDefinition(v, "definition") 1319 if len(errors) != 0 { 1320 t.Fatalf("%q should be a valid Step Function State Machine definition: %v", v, errors) 1321 } 1322 } 1323 1324 for _, v := range invalidDefinitions { 1325 _, errors := validateSfnStateMachineDefinition(v, "definition") 1326 if len(errors) == 0 { 1327 t.Fatalf("%q should not be a valid Step Function State Machine definition", v) 1328 } 1329 } 1330 } 1331 1332 func TestValidateStepFunctionStateMachineName(t *testing.T) { 1333 validTypes := []string{ 1334 "foo", 1335 "BAR", 1336 "FooBar123", 1337 "FooBar123Baz-_", 1338 } 1339 1340 invalidTypes := []string{ 1341 "foo bar", 1342 "foo<bar>", 1343 "foo{bar}", 1344 "foo[bar]", 1345 "foo*bar", 1346 "foo?bar", 1347 "foo#bar", 1348 "foo%bar", 1349 "foo\bar", 1350 "foo^bar", 1351 "foo|bar", 1352 "foo~bar", 1353 "foo$bar", 1354 "foo&bar", 1355 "foo,bar", 1356 "foo:bar", 1357 "foo;bar", 1358 "foo/bar", 1359 strings.Repeat("W", 81), // length > 80 1360 } 1361 1362 for _, v := range validTypes { 1363 _, errors := validateSfnStateMachineName(v, "name") 1364 if len(errors) != 0 { 1365 t.Fatalf("%q should be a valid Step Function State Machine name: %v", v, errors) 1366 } 1367 } 1368 1369 for _, v := range invalidTypes { 1370 _, errors := validateSfnStateMachineName(v, "name") 1371 if len(errors) == 0 { 1372 t.Fatalf("%q should not be a valid Step Function State Machine name", v) 1373 } 1374 } 1375 } 1376 1377 func TestValidateEmrEbsVolumeType(t *testing.T) { 1378 cases := []struct { 1379 VolType string 1380 ErrCount int 1381 }{ 1382 { 1383 VolType: "gp2", 1384 ErrCount: 0, 1385 }, 1386 { 1387 VolType: "io1", 1388 ErrCount: 0, 1389 }, 1390 { 1391 VolType: "standard", 1392 ErrCount: 0, 1393 }, 1394 { 1395 VolType: "stand", 1396 ErrCount: 1, 1397 }, 1398 { 1399 VolType: "io", 1400 ErrCount: 1, 1401 }, 1402 { 1403 VolType: "gp1", 1404 ErrCount: 1, 1405 }, 1406 { 1407 VolType: "fast-disk", 1408 ErrCount: 1, 1409 }, 1410 } 1411 1412 for _, tc := range cases { 1413 _, errors := validateAwsEmrEbsVolumeType(tc.VolType, "volume") 1414 1415 if len(errors) != tc.ErrCount { 1416 t.Fatalf("Expected %d errors, got %d: %s", tc.ErrCount, len(errors), errors) 1417 } 1418 } 1419 } 1420 1421 func TestValidateAppautoscalingScalableDimension(t *testing.T) { 1422 cases := []struct { 1423 Value string 1424 ErrCount int 1425 }{ 1426 { 1427 Value: "ecs:service:DesiredCount", 1428 ErrCount: 0, 1429 }, 1430 { 1431 Value: "ec2:spot-fleet-request:TargetCapacity", 1432 ErrCount: 0, 1433 }, 1434 { 1435 Value: "ec2:service:DesiredCount", 1436 ErrCount: 1, 1437 }, 1438 { 1439 Value: "ecs:spot-fleet-request:TargetCapacity", 1440 ErrCount: 1, 1441 }, 1442 { 1443 Value: "", 1444 ErrCount: 1, 1445 }, 1446 } 1447 1448 for _, tc := range cases { 1449 _, errors := validateAppautoscalingScalableDimension(tc.Value, "scalable_dimension") 1450 if len(errors) != tc.ErrCount { 1451 t.Fatalf("Scalable Dimension validation failed for value %q: %q", tc.Value, errors) 1452 } 1453 } 1454 } 1455 1456 func TestValidateAppautoscalingServiceNamespace(t *testing.T) { 1457 cases := []struct { 1458 Value string 1459 ErrCount int 1460 }{ 1461 { 1462 Value: "ecs", 1463 ErrCount: 0, 1464 }, 1465 { 1466 Value: "ec2", 1467 ErrCount: 0, 1468 }, 1469 { 1470 Value: "autoscaling", 1471 ErrCount: 1, 1472 }, 1473 { 1474 Value: "s3", 1475 ErrCount: 1, 1476 }, 1477 { 1478 Value: "es", 1479 ErrCount: 1, 1480 }, 1481 { 1482 Value: "", 1483 ErrCount: 1, 1484 }, 1485 } 1486 1487 for _, tc := range cases { 1488 _, errors := validateAppautoscalingServiceNamespace(tc.Value, "service_namespace") 1489 if len(errors) != tc.ErrCount { 1490 t.Fatalf("Service Namespace validation failed for value %q: %q", tc.Value, errors) 1491 } 1492 } 1493 } 1494 1495 func TestValidateDmsEndpointId(t *testing.T) { 1496 validIds := []string{ 1497 "tf-test-endpoint-1", 1498 "tfTestEndpoint", 1499 } 1500 1501 for _, s := range validIds { 1502 _, errors := validateDmsEndpointId(s, "endpoint_id") 1503 if len(errors) > 0 { 1504 t.Fatalf("%q should be a valid endpoint id: %v", s, errors) 1505 } 1506 } 1507 1508 invalidIds := []string{ 1509 "tf_test_endpoint_1", 1510 "tf.test.endpoint.1", 1511 "tf test endpoint 1", 1512 "tf-test-endpoint-1!", 1513 "tf-test-endpoint-1-", 1514 "tf-test-endpoint--1", 1515 "tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1", 1516 } 1517 1518 for _, s := range invalidIds { 1519 _, errors := validateDmsEndpointId(s, "endpoint_id") 1520 if len(errors) == 0 { 1521 t.Fatalf("%q should not be a valid endpoint id: %v", s, errors) 1522 } 1523 } 1524 } 1525 1526 func TestValidateDmsCertificateId(t *testing.T) { 1527 validIds := []string{ 1528 "tf-test-certificate-1", 1529 "tfTestEndpoint", 1530 } 1531 1532 for _, s := range validIds { 1533 _, errors := validateDmsCertificateId(s, "certificate_id") 1534 if len(errors) > 0 { 1535 t.Fatalf("%q should be a valid certificate id: %v", s, errors) 1536 } 1537 } 1538 1539 invalidIds := []string{ 1540 "tf_test_certificate_1", 1541 "tf.test.certificate.1", 1542 "tf test certificate 1", 1543 "tf-test-certificate-1!", 1544 "tf-test-certificate-1-", 1545 "tf-test-certificate--1", 1546 "tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1", 1547 } 1548 1549 for _, s := range invalidIds { 1550 _, errors := validateDmsEndpointId(s, "certificate_id") 1551 if len(errors) == 0 { 1552 t.Fatalf("%q should not be a valid certificate id: %v", s, errors) 1553 } 1554 } 1555 } 1556 1557 func TestValidateDmsReplicationInstanceId(t *testing.T) { 1558 validIds := []string{ 1559 "tf-test-replication-instance-1", 1560 "tfTestReplicaitonInstance", 1561 } 1562 1563 for _, s := range validIds { 1564 _, errors := validateDmsReplicationInstanceId(s, "replicaiton_instance_id") 1565 if len(errors) > 0 { 1566 t.Fatalf("%q should be a valid replication instance id: %v", s, errors) 1567 } 1568 } 1569 1570 invalidIds := []string{ 1571 "tf_test_replication-instance_1", 1572 "tf.test.replication.instance.1", 1573 "tf test replication instance 1", 1574 "tf-test-replication-instance-1!", 1575 "tf-test-replication-instance-1-", 1576 "tf-test-replication-instance--1", 1577 "tf-test-replication-instance-1tf-test-replication-instance-1tf-test-replication-instance-1", 1578 } 1579 1580 for _, s := range invalidIds { 1581 _, errors := validateDmsReplicationInstanceId(s, "replication_instance_id") 1582 if len(errors) == 0 { 1583 t.Fatalf("%q should not be a valid replication instance id: %v", s, errors) 1584 } 1585 } 1586 } 1587 1588 func TestValidateDmsReplicationSubnetGroupId(t *testing.T) { 1589 validIds := []string{ 1590 "tf-test-replication-subnet-group-1", 1591 "tf_test_replication_subnet_group_1", 1592 "tf.test.replication.subnet.group.1", 1593 "tf test replication subnet group 1", 1594 "tfTestReplicationSubnetGroup", 1595 } 1596 1597 for _, s := range validIds { 1598 _, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id") 1599 if len(errors) > 0 { 1600 t.Fatalf("%q should be a valid replication subnet group id: %v", s, errors) 1601 } 1602 } 1603 1604 invalidIds := []string{ 1605 "default", 1606 "tf-test-replication-subnet-group-1!", 1607 "tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1", 1608 } 1609 1610 for _, s := range invalidIds { 1611 _, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id") 1612 if len(errors) == 0 { 1613 t.Fatalf("%q should not be a valid replication subnet group id: %v", s, errors) 1614 } 1615 } 1616 } 1617 1618 func TestValidateDmsReplicationTaskId(t *testing.T) { 1619 validIds := []string{ 1620 "tf-test-replication-task-1", 1621 "tfTestReplicationTask", 1622 } 1623 1624 for _, s := range validIds { 1625 _, errors := validateDmsReplicationTaskId(s, "replication_task_id") 1626 if len(errors) > 0 { 1627 t.Fatalf("%q should be a valid replication task id: %v", s, errors) 1628 } 1629 } 1630 1631 invalidIds := []string{ 1632 "tf_test_replication_task_1", 1633 "tf.test.replication.task.1", 1634 "tf test replication task 1", 1635 "tf-test-replication-task-1!", 1636 "tf-test-replication-task-1-", 1637 "tf-test-replication-task--1", 1638 "tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1", 1639 } 1640 1641 for _, s := range invalidIds { 1642 _, errors := validateDmsReplicationTaskId(s, "replication_task_id") 1643 if len(errors) == 0 { 1644 t.Fatalf("%q should not be a valid replication task id: %v", s, errors) 1645 } 1646 } 1647 } 1648 1649 func TestValidateAccountAlias(t *testing.T) { 1650 validAliases := []string{ 1651 "tf-alias", 1652 "0tf-alias1", 1653 } 1654 1655 for _, s := range validAliases { 1656 _, errors := validateAccountAlias(s, "account_alias") 1657 if len(errors) > 0 { 1658 t.Fatalf("%q should be a valid account alias: %v", s, errors) 1659 } 1660 } 1661 1662 invalidAliases := []string{ 1663 "tf", 1664 "-tf", 1665 "tf-", 1666 "TF-Alias", 1667 "tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias", 1668 } 1669 1670 for _, s := range invalidAliases { 1671 _, errors := validateAccountAlias(s, "account_alias") 1672 if len(errors) == 0 { 1673 t.Fatalf("%q should not be a valid account alias: %v", s, errors) 1674 } 1675 } 1676 } 1677 1678 func TestValidateIamRoleProfileName(t *testing.T) { 1679 validNames := []string{ 1680 "tf-test-role-profile-1", 1681 } 1682 1683 for _, s := range validNames { 1684 _, errors := validateIamRolePolicyName(s, "name") 1685 if len(errors) > 0 { 1686 t.Fatalf("%q should be a valid IAM role policy name: %v", s, errors) 1687 } 1688 } 1689 1690 invalidNames := []string{ 1691 "invalid#name", 1692 "this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long", 1693 } 1694 1695 for _, s := range invalidNames { 1696 _, errors := validateIamRolePolicyName(s, "name") 1697 if len(errors) == 0 { 1698 t.Fatalf("%q should not be a valid IAM role policy name: %v", s, errors) 1699 } 1700 } 1701 } 1702 1703 func TestValidateIamRoleProfileNamePrefix(t *testing.T) { 1704 validNamePrefixes := []string{ 1705 "tf-test-role-profile-", 1706 } 1707 1708 for _, s := range validNamePrefixes { 1709 _, errors := validateIamRolePolicyNamePrefix(s, "name_prefix") 1710 if len(errors) > 0 { 1711 t.Fatalf("%q should be a valid IAM role policy name prefix: %v", s, errors) 1712 } 1713 } 1714 1715 invalidNamePrefixes := []string{ 1716 "invalid#name_prefix", 1717 "this-is-a-very-long-role-policy-name-prefix-this-is-a-very-long-role-policy-name-prefix-this-is-a-very-", 1718 } 1719 1720 for _, s := range invalidNamePrefixes { 1721 _, errors := validateIamRolePolicyNamePrefix(s, "name_prefix") 1722 if len(errors) == 0 { 1723 t.Fatalf("%q should not be a valid IAM role policy name prefix: %v", s, errors) 1724 } 1725 } 1726 } 1727 1728 func TestValidateApiGatewayUsagePlanQuotaSettingsPeriod(t *testing.T) { 1729 validEntries := []string{ 1730 "DAY", 1731 "WEEK", 1732 "MONTH", 1733 } 1734 1735 invalidEntries := []string{ 1736 "fooBAR", 1737 "foobar45Baz", 1738 "foobar45Baz@!", 1739 } 1740 1741 for _, v := range validEntries { 1742 _, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name") 1743 if len(errors) != 0 { 1744 t.Fatalf("%q should be a valid API Gateway Quota Settings Period: %v", v, errors) 1745 } 1746 } 1747 1748 for _, v := range invalidEntries { 1749 _, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name") 1750 if len(errors) == 0 { 1751 t.Fatalf("%q should not be a API Gateway Quota Settings Period", v) 1752 } 1753 } 1754 } 1755 1756 func TestValidateApiGatewayUsagePlanQuotaSettings(t *testing.T) { 1757 cases := []struct { 1758 Offset int 1759 Period string 1760 ErrCount int 1761 }{ 1762 { 1763 Offset: 0, 1764 Period: "DAY", 1765 ErrCount: 0, 1766 }, 1767 { 1768 Offset: -1, 1769 Period: "DAY", 1770 ErrCount: 1, 1771 }, 1772 { 1773 Offset: 1, 1774 Period: "DAY", 1775 ErrCount: 1, 1776 }, 1777 { 1778 Offset: 0, 1779 Period: "WEEK", 1780 ErrCount: 0, 1781 }, 1782 { 1783 Offset: 6, 1784 Period: "WEEK", 1785 ErrCount: 0, 1786 }, 1787 { 1788 Offset: -1, 1789 Period: "WEEK", 1790 ErrCount: 1, 1791 }, 1792 { 1793 Offset: 7, 1794 Period: "WEEK", 1795 ErrCount: 1, 1796 }, 1797 { 1798 Offset: 0, 1799 Period: "MONTH", 1800 ErrCount: 0, 1801 }, 1802 { 1803 Offset: 27, 1804 Period: "MONTH", 1805 ErrCount: 0, 1806 }, 1807 { 1808 Offset: -1, 1809 Period: "MONTH", 1810 ErrCount: 1, 1811 }, 1812 { 1813 Offset: 28, 1814 Period: "MONTH", 1815 ErrCount: 1, 1816 }, 1817 } 1818 1819 for _, tc := range cases { 1820 m := make(map[string]interface{}) 1821 m["offset"] = tc.Offset 1822 m["period"] = tc.Period 1823 1824 errors := validateApiGatewayUsagePlanQuotaSettings(m) 1825 if len(errors) != tc.ErrCount { 1826 t.Fatalf("API Gateway Usage Plan Quota Settings validation failed: %v", errors) 1827 } 1828 } 1829 } 1830 1831 func TestValidateElbName(t *testing.T) { 1832 validNames := []string{ 1833 "tf-test-elb", 1834 } 1835 1836 for _, s := range validNames { 1837 _, errors := validateElbName(s, "name") 1838 if len(errors) > 0 { 1839 t.Fatalf("%q should be a valid ELB name: %v", s, errors) 1840 } 1841 } 1842 1843 invalidNames := []string{ 1844 "tf.test.elb.1", 1845 "tf-test-elb-tf-test-elb-tf-test-elb", 1846 "-tf-test-elb", 1847 "tf-test-elb-", 1848 } 1849 1850 for _, s := range invalidNames { 1851 _, errors := validateElbName(s, "name") 1852 if len(errors) == 0 { 1853 t.Fatalf("%q should not be a valid ELB name: %v", s, errors) 1854 } 1855 } 1856 } 1857 1858 func TestValidateElbNamePrefix(t *testing.T) { 1859 validNamePrefixes := []string{ 1860 "test-", 1861 } 1862 1863 for _, s := range validNamePrefixes { 1864 _, errors := validateElbNamePrefix(s, "name_prefix") 1865 if len(errors) > 0 { 1866 t.Fatalf("%q should be a valid ELB name prefix: %v", s, errors) 1867 } 1868 } 1869 1870 invalidNamePrefixes := []string{ 1871 "tf.test.elb.", 1872 "tf-test", 1873 "-test", 1874 } 1875 1876 for _, s := range invalidNamePrefixes { 1877 _, errors := validateElbNamePrefix(s, "name_prefix") 1878 if len(errors) == 0 { 1879 t.Fatalf("%q should not be a valid ELB name prefix: %v", s, errors) 1880 } 1881 } 1882 } 1883 1884 func TestValidateDbSubnetGroupName(t *testing.T) { 1885 cases := []struct { 1886 Value string 1887 ErrCount int 1888 }{ 1889 { 1890 Value: "tEsting", 1891 ErrCount: 1, 1892 }, 1893 { 1894 Value: "testing?", 1895 ErrCount: 1, 1896 }, 1897 { 1898 Value: "default", 1899 ErrCount: 1, 1900 }, 1901 { 1902 Value: randomString(300), 1903 ErrCount: 1, 1904 }, 1905 } 1906 1907 for _, tc := range cases { 1908 _, errors := validateDbSubnetGroupName(tc.Value, "aws_db_subnet_group") 1909 1910 if len(errors) != tc.ErrCount { 1911 t.Fatalf("Expected the DB Subnet Group name to trigger a validation error") 1912 } 1913 } 1914 } 1915 1916 func TestValidateDbSubnetGroupNamePrefix(t *testing.T) { 1917 cases := []struct { 1918 Value string 1919 ErrCount int 1920 }{ 1921 { 1922 Value: "tEsting", 1923 ErrCount: 1, 1924 }, 1925 { 1926 Value: "testing?", 1927 ErrCount: 1, 1928 }, 1929 { 1930 Value: randomString(230), 1931 ErrCount: 1, 1932 }, 1933 } 1934 1935 for _, tc := range cases { 1936 _, errors := validateDbSubnetGroupNamePrefix(tc.Value, "aws_db_subnet_group") 1937 1938 if len(errors) != tc.ErrCount { 1939 t.Fatalf("Expected the DB Subnet Group name prefix to trigger a validation error") 1940 } 1941 } 1942 } 1943 1944 func TestValidateDbOptionGroupName(t *testing.T) { 1945 cases := []struct { 1946 Value string 1947 ErrCount int 1948 }{ 1949 { 1950 Value: "testing123!", 1951 ErrCount: 1, 1952 }, 1953 { 1954 Value: "1testing123", 1955 ErrCount: 1, 1956 }, 1957 { 1958 Value: "testing--123", 1959 ErrCount: 1, 1960 }, 1961 { 1962 Value: "testing123-", 1963 ErrCount: 1, 1964 }, 1965 { 1966 Value: randomString(256), 1967 ErrCount: 1, 1968 }, 1969 } 1970 1971 for _, tc := range cases { 1972 _, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name") 1973 1974 if len(errors) != tc.ErrCount { 1975 t.Fatalf("Expected the DB Option Group Name to trigger a validation error") 1976 } 1977 } 1978 } 1979 1980 func TestValidateDbOptionGroupNamePrefix(t *testing.T) { 1981 cases := []struct { 1982 Value string 1983 ErrCount int 1984 }{ 1985 { 1986 Value: "testing123!", 1987 ErrCount: 1, 1988 }, 1989 { 1990 Value: "1testing123", 1991 ErrCount: 1, 1992 }, 1993 { 1994 Value: "testing--123", 1995 ErrCount: 1, 1996 }, 1997 { 1998 Value: randomString(230), 1999 ErrCount: 1, 2000 }, 2001 } 2002 2003 for _, tc := range cases { 2004 _, errors := validateDbOptionGroupNamePrefix(tc.Value, "aws_db_option_group_name") 2005 2006 if len(errors) != tc.ErrCount { 2007 t.Fatalf("Expected the DB Option Group name prefix to trigger a validation error") 2008 } 2009 } 2010 } 2011 2012 func TestValidateOpenIdURL(t *testing.T) { 2013 cases := []struct { 2014 Value string 2015 ErrCount int 2016 }{ 2017 { 2018 Value: "http://wrong.scheme.com", 2019 ErrCount: 1, 2020 }, 2021 { 2022 Value: "ftp://wrong.scheme.co.uk", 2023 ErrCount: 1, 2024 }, 2025 { 2026 Value: "%@invalidUrl", 2027 ErrCount: 1, 2028 }, 2029 { 2030 Value: "https://example.com/?query=param", 2031 ErrCount: 1, 2032 }, 2033 } 2034 2035 for _, tc := range cases { 2036 _, errors := validateOpenIdURL(tc.Value, "url") 2037 2038 if len(errors) != tc.ErrCount { 2039 t.Fatalf("Expected %d of OpenID URL validation errors, got %d", tc.ErrCount, len(errors)) 2040 } 2041 } 2042 } 2043 2044 func TestValidateAwsKmsName(t *testing.T) { 2045 cases := []struct { 2046 Value string 2047 ErrCount int 2048 }{ 2049 { 2050 Value: "alias/aws/s3", 2051 ErrCount: 0, 2052 }, 2053 { 2054 Value: "alias/hashicorp", 2055 ErrCount: 0, 2056 }, 2057 { 2058 Value: "hashicorp", 2059 ErrCount: 1, 2060 }, 2061 { 2062 Value: "hashicorp/terraform", 2063 ErrCount: 1, 2064 }, 2065 } 2066 2067 for _, tc := range cases { 2068 _, errors := validateAwsKmsName(tc.Value, "name") 2069 if len(errors) != tc.ErrCount { 2070 t.Fatalf("AWS KMS Alias Name validation failed: %v", errors) 2071 } 2072 } 2073 } 2074 2075 func TestValidateCognitoIdentityPoolName(t *testing.T) { 2076 validValues := []string{ 2077 "123", 2078 "1 2 3", 2079 "foo", 2080 "foo bar", 2081 "foo_bar", 2082 "1foo 2bar 3", 2083 } 2084 2085 for _, s := range validValues { 2086 _, errors := validateCognitoIdentityPoolName(s, "identity_pool_name") 2087 if len(errors) > 0 { 2088 t.Fatalf("%q should be a valid Cognito Identity Pool Name: %v", s, errors) 2089 } 2090 } 2091 2092 invalidValues := []string{ 2093 "1-2-3", 2094 "foo!", 2095 "foo-bar", 2096 "foo-bar", 2097 "foo1-bar2", 2098 } 2099 2100 for _, s := range invalidValues { 2101 _, errors := validateCognitoIdentityPoolName(s, "identity_pool_name") 2102 if len(errors) == 0 { 2103 t.Fatalf("%q should not be a valid Cognito Identity Pool Name: %v", s, errors) 2104 } 2105 } 2106 } 2107 2108 func TestValidateCognitoProviderDeveloperName(t *testing.T) { 2109 validValues := []string{ 2110 "1", 2111 "foo", 2112 "1.2", 2113 "foo1-bar2-baz3", 2114 "foo_bar", 2115 } 2116 2117 for _, s := range validValues { 2118 _, errors := validateCognitoProviderDeveloperName(s, "developer_provider_name") 2119 if len(errors) > 0 { 2120 t.Fatalf("%q should be a valid Cognito Provider Developer Name: %v", s, errors) 2121 } 2122 } 2123 2124 invalidValues := []string{ 2125 "foo!", 2126 "foo:bar", 2127 "foo/bar", 2128 "foo;bar", 2129 } 2130 2131 for _, s := range invalidValues { 2132 _, errors := validateCognitoProviderDeveloperName(s, "developer_provider_name") 2133 if len(errors) == 0 { 2134 t.Fatalf("%q should not be a valid Cognito Provider Developer Name: %v", s, errors) 2135 } 2136 } 2137 } 2138 2139 func TestValidateCognitoSupportedLoginProviders(t *testing.T) { 2140 validValues := []string{ 2141 "foo", 2142 "7346241598935552", 2143 "123456789012.apps.googleusercontent.com", 2144 "foo_bar", 2145 "foo;bar", 2146 "foo/bar", 2147 "foo-bar", 2148 "xvz1evFS4wEEPTGEFPHBog;kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw", 2149 strings.Repeat("W", 128), 2150 } 2151 2152 for _, s := range validValues { 2153 _, errors := validateCognitoSupportedLoginProviders(s, "supported_login_providers") 2154 if len(errors) > 0 { 2155 t.Fatalf("%q should be a valid Cognito Supported Login Providers: %v", s, errors) 2156 } 2157 } 2158 2159 invalidValues := []string{ 2160 "", 2161 strings.Repeat("W", 129), // > 128 2162 "foo:bar_baz", 2163 "foobar,foobaz", 2164 "foobar=foobaz", 2165 } 2166 2167 for _, s := range invalidValues { 2168 _, errors := validateCognitoSupportedLoginProviders(s, "supported_login_providers") 2169 if len(errors) == 0 { 2170 t.Fatalf("%q should not be a valid Cognito Supported Login Providers: %v", s, errors) 2171 } 2172 } 2173 } 2174 2175 func TestValidateCognitoIdentityProvidersClientId(t *testing.T) { 2176 validValues := []string{ 2177 "7lhlkkfbfb4q5kpp90urffao", 2178 "12345678", 2179 "foo_123", 2180 strings.Repeat("W", 128), 2181 } 2182 2183 for _, s := range validValues { 2184 _, errors := validateCognitoIdentityProvidersClientId(s, "client_id") 2185 if len(errors) > 0 { 2186 t.Fatalf("%q should be a valid Cognito Identity Provider Client ID: %v", s, errors) 2187 } 2188 } 2189 2190 invalidValues := []string{ 2191 "", 2192 strings.Repeat("W", 129), // > 128 2193 "foo-bar", 2194 "foo:bar", 2195 "foo;bar", 2196 } 2197 2198 for _, s := range invalidValues { 2199 _, errors := validateCognitoIdentityProvidersClientId(s, "client_id") 2200 if len(errors) == 0 { 2201 t.Fatalf("%q should not be a valid Cognito Identity Provider Client ID: %v", s, errors) 2202 } 2203 } 2204 } 2205 2206 func TestValidateCognitoIdentityProvidersProviderName(t *testing.T) { 2207 validValues := []string{ 2208 "foo", 2209 "7346241598935552", 2210 "foo_bar", 2211 "foo:bar", 2212 "foo/bar", 2213 "foo-bar", 2214 "cognito-idp.us-east-1.amazonaws.com/us-east-1_Zr231apJu", 2215 strings.Repeat("W", 128), 2216 } 2217 2218 for _, s := range validValues { 2219 _, errors := validateCognitoIdentityProvidersProviderName(s, "provider_name") 2220 if len(errors) > 0 { 2221 t.Fatalf("%q should be a valid Cognito Identity Provider Name: %v", s, errors) 2222 } 2223 } 2224 2225 invalidValues := []string{ 2226 "", 2227 strings.Repeat("W", 129), // > 128 2228 "foo;bar_baz", 2229 "foobar,foobaz", 2230 "foobar=foobaz", 2231 } 2232 2233 for _, s := range invalidValues { 2234 _, errors := validateCognitoIdentityProvidersProviderName(s, "provider_name") 2235 if len(errors) == 0 { 2236 t.Fatalf("%q should not be a valid Cognito Identity Provider Name: %v", s, errors) 2237 } 2238 } 2239 } 2240 2241 func TestValidateWafMetricName(t *testing.T) { 2242 validNames := []string{ 2243 "testrule", 2244 "testRule", 2245 "testRule123", 2246 } 2247 for _, v := range validNames { 2248 _, errors := validateWafMetricName(v, "name") 2249 if len(errors) != 0 { 2250 t.Fatalf("%q should be a valid WAF metric name: %q", v, errors) 2251 } 2252 } 2253 2254 invalidNames := []string{ 2255 "!", 2256 "/", 2257 " ", 2258 ":", 2259 ";", 2260 "white space", 2261 "/slash-at-the-beginning", 2262 "slash-at-the-end/", 2263 } 2264 for _, v := range invalidNames { 2265 _, errors := validateWafMetricName(v, "name") 2266 if len(errors) == 0 { 2267 t.Fatalf("%q should be an invalid WAF metric name", v) 2268 } 2269 } 2270 } 2271 2272 func TestValidateIamRoleDescription(t *testing.T) { 2273 validNames := []string{ 2274 "This 1s a D3scr!pti0n with weird content: @ #^ù£ê®æ ø]ŒîÏî~ÈÙ£÷=,ë", 2275 strings.Repeat("W", 1000), 2276 } 2277 for _, v := range validNames { 2278 _, errors := validateIamRoleDescription(v, "description") 2279 if len(errors) != 0 { 2280 t.Fatalf("%q should be a valid IAM Role Description: %q", v, errors) 2281 } 2282 } 2283 2284 invalidNames := []string{ 2285 strings.Repeat("W", 1001), // > 1000 2286 } 2287 for _, v := range invalidNames { 2288 _, errors := validateIamRoleDescription(v, "description") 2289 if len(errors) == 0 { 2290 t.Fatalf("%q should be an invalid IAM Role Description", v) 2291 } 2292 } 2293 } 2294 2295 func TestValidateSsmParameterType(t *testing.T) { 2296 validTypes := []string{ 2297 "String", 2298 "StringList", 2299 "SecureString", 2300 } 2301 for _, v := range validTypes { 2302 _, errors := validateSsmParameterType(v, "name") 2303 if len(errors) != 0 { 2304 t.Fatalf("%q should be a valid SSM parameter type: %q", v, errors) 2305 } 2306 } 2307 2308 invalidTypes := []string{ 2309 "foo", 2310 "string", 2311 "Securestring", 2312 } 2313 for _, v := range invalidTypes { 2314 _, errors := validateSsmParameterType(v, "name") 2315 if len(errors) == 0 { 2316 t.Fatalf("%q should be an invalid SSM parameter type", v) 2317 } 2318 } 2319 }