github.com/articulate/terraform@v0.6.13-0.20160303003731-8d31c93862de/builtin/providers/aws/structure_test.go (about) 1 package aws 2 3 import ( 4 "reflect" 5 "strings" 6 "testing" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/service/autoscaling" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/aws/aws-sdk-go/service/elasticache" 12 "github.com/aws/aws-sdk-go/service/elb" 13 "github.com/aws/aws-sdk-go/service/rds" 14 "github.com/aws/aws-sdk-go/service/redshift" 15 "github.com/aws/aws-sdk-go/service/route53" 16 "github.com/hashicorp/terraform/flatmap" 17 "github.com/hashicorp/terraform/helper/schema" 18 ) 19 20 // Returns test configuration 21 func testConf() map[string]string { 22 return map[string]string{ 23 "listener.#": "1", 24 "listener.0.lb_port": "80", 25 "listener.0.lb_protocol": "http", 26 "listener.0.instance_port": "8000", 27 "listener.0.instance_protocol": "http", 28 "availability_zones.#": "2", 29 "availability_zones.0": "us-east-1a", 30 "availability_zones.1": "us-east-1b", 31 "ingress.#": "1", 32 "ingress.0.protocol": "icmp", 33 "ingress.0.from_port": "1", 34 "ingress.0.to_port": "-1", 35 "ingress.0.cidr_blocks.#": "1", 36 "ingress.0.cidr_blocks.0": "0.0.0.0/0", 37 "ingress.0.security_groups.#": "2", 38 "ingress.0.security_groups.0": "sg-11111", 39 "ingress.0.security_groups.1": "foo/sg-22222", 40 } 41 } 42 43 func TestExpandIPPerms(t *testing.T) { 44 hash := schema.HashString 45 46 expanded := []interface{}{ 47 map[string]interface{}{ 48 "protocol": "icmp", 49 "from_port": 1, 50 "to_port": -1, 51 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 52 "security_groups": schema.NewSet(hash, []interface{}{ 53 "sg-11111", 54 "foo/sg-22222", 55 }), 56 }, 57 map[string]interface{}{ 58 "protocol": "icmp", 59 "from_port": 1, 60 "to_port": -1, 61 "self": true, 62 }, 63 } 64 group := &ec2.SecurityGroup{ 65 GroupId: aws.String("foo"), 66 VpcId: aws.String("bar"), 67 } 68 perms, err := expandIPPerms(group, expanded) 69 if err != nil { 70 t.Fatalf("error expanding perms: %v", err) 71 } 72 73 expected := []ec2.IpPermission{ 74 ec2.IpPermission{ 75 IpProtocol: aws.String("icmp"), 76 FromPort: aws.Int64(int64(1)), 77 ToPort: aws.Int64(int64(-1)), 78 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 79 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 80 &ec2.UserIdGroupPair{ 81 UserId: aws.String("foo"), 82 GroupId: aws.String("sg-22222"), 83 }, 84 &ec2.UserIdGroupPair{ 85 GroupId: aws.String("sg-22222"), 86 }, 87 }, 88 }, 89 ec2.IpPermission{ 90 IpProtocol: aws.String("icmp"), 91 FromPort: aws.Int64(int64(1)), 92 ToPort: aws.Int64(int64(-1)), 93 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 94 &ec2.UserIdGroupPair{ 95 UserId: aws.String("foo"), 96 }, 97 }, 98 }, 99 } 100 101 exp := expected[0] 102 perm := perms[0] 103 104 if *exp.FromPort != *perm.FromPort { 105 t.Fatalf( 106 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 107 *perm.FromPort, 108 *exp.FromPort) 109 } 110 111 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 112 t.Fatalf( 113 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 114 *perm.IpRanges[0].CidrIp, 115 *exp.IpRanges[0].CidrIp) 116 } 117 118 if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId { 119 t.Fatalf( 120 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 121 *perm.UserIdGroupPairs[0].UserId, 122 *exp.UserIdGroupPairs[0].UserId) 123 } 124 125 } 126 127 func TestExpandIPPerms_NegOneProtocol(t *testing.T) { 128 hash := schema.HashString 129 130 expanded := []interface{}{ 131 map[string]interface{}{ 132 "protocol": "-1", 133 "from_port": 0, 134 "to_port": 0, 135 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 136 "security_groups": schema.NewSet(hash, []interface{}{ 137 "sg-11111", 138 "foo/sg-22222", 139 }), 140 }, 141 } 142 group := &ec2.SecurityGroup{ 143 GroupId: aws.String("foo"), 144 VpcId: aws.String("bar"), 145 } 146 147 perms, err := expandIPPerms(group, expanded) 148 if err != nil { 149 t.Fatalf("error expanding perms: %v", err) 150 } 151 152 expected := []ec2.IpPermission{ 153 ec2.IpPermission{ 154 IpProtocol: aws.String("-1"), 155 FromPort: aws.Int64(int64(0)), 156 ToPort: aws.Int64(int64(0)), 157 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 158 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 159 &ec2.UserIdGroupPair{ 160 UserId: aws.String("foo"), 161 GroupId: aws.String("sg-22222"), 162 }, 163 &ec2.UserIdGroupPair{ 164 GroupId: aws.String("sg-22222"), 165 }, 166 }, 167 }, 168 } 169 170 exp := expected[0] 171 perm := perms[0] 172 173 if *exp.FromPort != *perm.FromPort { 174 t.Fatalf( 175 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 176 *perm.FromPort, 177 *exp.FromPort) 178 } 179 180 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 181 t.Fatalf( 182 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 183 *perm.IpRanges[0].CidrIp, 184 *exp.IpRanges[0].CidrIp) 185 } 186 187 if *exp.UserIdGroupPairs[0].UserId != *perm.UserIdGroupPairs[0].UserId { 188 t.Fatalf( 189 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 190 *perm.UserIdGroupPairs[0].UserId, 191 *exp.UserIdGroupPairs[0].UserId) 192 } 193 194 // Now test the error case. This *should* error when either from_port 195 // or to_port is not zero, but protocol is "-1". 196 errorCase := []interface{}{ 197 map[string]interface{}{ 198 "protocol": "-1", 199 "from_port": 0, 200 "to_port": 65535, 201 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 202 "security_groups": schema.NewSet(hash, []interface{}{ 203 "sg-11111", 204 "foo/sg-22222", 205 }), 206 }, 207 } 208 securityGroups := &ec2.SecurityGroup{ 209 GroupId: aws.String("foo"), 210 VpcId: aws.String("bar"), 211 } 212 213 _, expandErr := expandIPPerms(securityGroups, errorCase) 214 if expandErr == nil { 215 t.Fatal("expandIPPerms should have errored!") 216 } 217 } 218 219 func TestExpandIPPerms_nonVPC(t *testing.T) { 220 hash := schema.HashString 221 222 expanded := []interface{}{ 223 map[string]interface{}{ 224 "protocol": "icmp", 225 "from_port": 1, 226 "to_port": -1, 227 "cidr_blocks": []interface{}{"0.0.0.0/0"}, 228 "security_groups": schema.NewSet(hash, []interface{}{ 229 "sg-11111", 230 "foo/sg-22222", 231 }), 232 }, 233 map[string]interface{}{ 234 "protocol": "icmp", 235 "from_port": 1, 236 "to_port": -1, 237 "self": true, 238 }, 239 } 240 group := &ec2.SecurityGroup{ 241 GroupName: aws.String("foo"), 242 } 243 perms, err := expandIPPerms(group, expanded) 244 if err != nil { 245 t.Fatalf("error expanding perms: %v", err) 246 } 247 248 expected := []ec2.IpPermission{ 249 ec2.IpPermission{ 250 IpProtocol: aws.String("icmp"), 251 FromPort: aws.Int64(int64(1)), 252 ToPort: aws.Int64(int64(-1)), 253 IpRanges: []*ec2.IpRange{&ec2.IpRange{CidrIp: aws.String("0.0.0.0/0")}}, 254 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 255 &ec2.UserIdGroupPair{ 256 GroupName: aws.String("sg-22222"), 257 }, 258 &ec2.UserIdGroupPair{ 259 GroupName: aws.String("sg-22222"), 260 }, 261 }, 262 }, 263 ec2.IpPermission{ 264 IpProtocol: aws.String("icmp"), 265 FromPort: aws.Int64(int64(1)), 266 ToPort: aws.Int64(int64(-1)), 267 UserIdGroupPairs: []*ec2.UserIdGroupPair{ 268 &ec2.UserIdGroupPair{ 269 GroupName: aws.String("foo"), 270 }, 271 }, 272 }, 273 } 274 275 exp := expected[0] 276 perm := perms[0] 277 278 if *exp.FromPort != *perm.FromPort { 279 t.Fatalf( 280 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 281 *perm.FromPort, 282 *exp.FromPort) 283 } 284 285 if *exp.IpRanges[0].CidrIp != *perm.IpRanges[0].CidrIp { 286 t.Fatalf( 287 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 288 *perm.IpRanges[0].CidrIp, 289 *exp.IpRanges[0].CidrIp) 290 } 291 } 292 293 func TestExpandListeners(t *testing.T) { 294 expanded := []interface{}{ 295 map[string]interface{}{ 296 "instance_port": 8000, 297 "lb_port": 80, 298 "instance_protocol": "http", 299 "lb_protocol": "http", 300 }, 301 map[string]interface{}{ 302 "instance_port": 8000, 303 "lb_port": 80, 304 "instance_protocol": "https", 305 "lb_protocol": "https", 306 "ssl_certificate_id": "something", 307 }, 308 } 309 listeners, err := expandListeners(expanded) 310 if err != nil { 311 t.Fatalf("bad: %#v", err) 312 } 313 314 expected := &elb.Listener{ 315 InstancePort: aws.Int64(int64(8000)), 316 LoadBalancerPort: aws.Int64(int64(80)), 317 InstanceProtocol: aws.String("http"), 318 Protocol: aws.String("http"), 319 } 320 321 if !reflect.DeepEqual(listeners[0], expected) { 322 t.Fatalf( 323 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 324 listeners[0], 325 expected) 326 } 327 } 328 329 // this test should produce an error from expandlisteners on an invalid 330 // combination 331 func TestExpandListeners_invalid(t *testing.T) { 332 expanded := []interface{}{ 333 map[string]interface{}{ 334 "instance_port": 8000, 335 "lb_port": 80, 336 "instance_protocol": "http", 337 "lb_protocol": "http", 338 "ssl_certificate_id": "something", 339 }, 340 } 341 _, err := expandListeners(expanded) 342 if err != nil { 343 // Check the error we got 344 if !strings.Contains(err.Error(), "ssl_certificate_id may be set only when protocol") { 345 t.Fatalf("Got error in TestExpandListeners_invalid, but not what we expected: %s", err) 346 } 347 } 348 349 if err == nil { 350 t.Fatalf("Expected TestExpandListeners_invalid to fail, but passed") 351 } 352 } 353 354 func TestFlattenHealthCheck(t *testing.T) { 355 cases := []struct { 356 Input *elb.HealthCheck 357 Output []map[string]interface{} 358 }{ 359 { 360 Input: &elb.HealthCheck{ 361 UnhealthyThreshold: aws.Int64(int64(10)), 362 HealthyThreshold: aws.Int64(int64(10)), 363 Target: aws.String("HTTP:80/"), 364 Timeout: aws.Int64(int64(30)), 365 Interval: aws.Int64(int64(30)), 366 }, 367 Output: []map[string]interface{}{ 368 map[string]interface{}{ 369 "unhealthy_threshold": int64(10), 370 "healthy_threshold": int64(10), 371 "target": "HTTP:80/", 372 "timeout": int64(30), 373 "interval": int64(30), 374 }, 375 }, 376 }, 377 } 378 379 for _, tc := range cases { 380 output := flattenHealthCheck(tc.Input) 381 if !reflect.DeepEqual(output, tc.Output) { 382 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 383 } 384 } 385 } 386 387 func TestExpandStringList(t *testing.T) { 388 expanded := flatmap.Expand(testConf(), "availability_zones").([]interface{}) 389 stringList := expandStringList(expanded) 390 expected := []*string{ 391 aws.String("us-east-1a"), 392 aws.String("us-east-1b"), 393 } 394 395 if !reflect.DeepEqual(stringList, expected) { 396 t.Fatalf( 397 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 398 stringList, 399 expected) 400 } 401 402 } 403 404 func TestExpandParameters(t *testing.T) { 405 expanded := []interface{}{ 406 map[string]interface{}{ 407 "name": "character_set_client", 408 "value": "utf8", 409 "apply_method": "immediate", 410 }, 411 } 412 parameters, err := expandParameters(expanded) 413 if err != nil { 414 t.Fatalf("bad: %#v", err) 415 } 416 417 expected := &rds.Parameter{ 418 ParameterName: aws.String("character_set_client"), 419 ParameterValue: aws.String("utf8"), 420 ApplyMethod: aws.String("immediate"), 421 } 422 423 if !reflect.DeepEqual(parameters[0], expected) { 424 t.Fatalf( 425 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 426 parameters[0], 427 expected) 428 } 429 } 430 431 func TestexpandRedshiftParameters(t *testing.T) { 432 expanded := []interface{}{ 433 map[string]interface{}{ 434 "name": "character_set_client", 435 "value": "utf8", 436 }, 437 } 438 parameters, err := expandRedshiftParameters(expanded) 439 if err != nil { 440 t.Fatalf("bad: %#v", err) 441 } 442 443 expected := &redshift.Parameter{ 444 ParameterName: aws.String("character_set_client"), 445 ParameterValue: aws.String("utf8"), 446 } 447 448 if !reflect.DeepEqual(parameters[0], expected) { 449 t.Fatalf( 450 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 451 parameters[0], 452 expected) 453 } 454 } 455 456 func TestexpandElasticacheParameters(t *testing.T) { 457 expanded := []interface{}{ 458 map[string]interface{}{ 459 "name": "activerehashing", 460 "value": "yes", 461 "apply_method": "immediate", 462 }, 463 } 464 parameters, err := expandElastiCacheParameters(expanded) 465 if err != nil { 466 t.Fatalf("bad: %#v", err) 467 } 468 469 expected := &elasticache.ParameterNameValue{ 470 ParameterName: aws.String("activerehashing"), 471 ParameterValue: aws.String("yes"), 472 } 473 474 if !reflect.DeepEqual(parameters[0], expected) { 475 t.Fatalf( 476 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 477 parameters[0], 478 expected) 479 } 480 } 481 482 func TestFlattenParameters(t *testing.T) { 483 cases := []struct { 484 Input []*rds.Parameter 485 Output []map[string]interface{} 486 }{ 487 { 488 Input: []*rds.Parameter{ 489 &rds.Parameter{ 490 ParameterName: aws.String("character_set_client"), 491 ParameterValue: aws.String("utf8"), 492 }, 493 }, 494 Output: []map[string]interface{}{ 495 map[string]interface{}{ 496 "name": "character_set_client", 497 "value": "utf8", 498 }, 499 }, 500 }, 501 } 502 503 for _, tc := range cases { 504 output := flattenParameters(tc.Input) 505 if !reflect.DeepEqual(output, tc.Output) { 506 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 507 } 508 } 509 } 510 511 func TestflattenRedshiftParameters(t *testing.T) { 512 cases := []struct { 513 Input []*redshift.Parameter 514 Output []map[string]interface{} 515 }{ 516 { 517 Input: []*redshift.Parameter{ 518 &redshift.Parameter{ 519 ParameterName: aws.String("character_set_client"), 520 ParameterValue: aws.String("utf8"), 521 }, 522 }, 523 Output: []map[string]interface{}{ 524 map[string]interface{}{ 525 "name": "character_set_client", 526 "value": "utf8", 527 }, 528 }, 529 }, 530 } 531 532 for _, tc := range cases { 533 output := flattenRedshiftParameters(tc.Input) 534 if !reflect.DeepEqual(output, tc.Output) { 535 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 536 } 537 } 538 } 539 540 func TestflattenElasticacheParameters(t *testing.T) { 541 cases := []struct { 542 Input []*elasticache.Parameter 543 Output []map[string]interface{} 544 }{ 545 { 546 Input: []*elasticache.Parameter{ 547 &elasticache.Parameter{ 548 ParameterName: aws.String("activerehashing"), 549 ParameterValue: aws.String("yes"), 550 }, 551 }, 552 Output: []map[string]interface{}{ 553 map[string]interface{}{ 554 "name": "activerehashing", 555 "value": "yes", 556 }, 557 }, 558 }, 559 } 560 561 for _, tc := range cases { 562 output := flattenElastiCacheParameters(tc.Input) 563 if !reflect.DeepEqual(output, tc.Output) { 564 t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) 565 } 566 } 567 } 568 569 func TestExpandInstanceString(t *testing.T) { 570 571 expected := []*elb.Instance{ 572 &elb.Instance{InstanceId: aws.String("test-one")}, 573 &elb.Instance{InstanceId: aws.String("test-two")}, 574 } 575 576 ids := []interface{}{ 577 "test-one", 578 "test-two", 579 } 580 581 expanded := expandInstanceString(ids) 582 583 if !reflect.DeepEqual(expanded, expected) { 584 t.Fatalf("Expand Instance String output did not match.\nGot:\n%#v\n\nexpected:\n%#v", expanded, expected) 585 } 586 } 587 588 func TestFlattenNetworkInterfacesPrivateIPAddresses(t *testing.T) { 589 expanded := []*ec2.NetworkInterfacePrivateIpAddress{ 590 &ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.1")}, 591 &ec2.NetworkInterfacePrivateIpAddress{PrivateIpAddress: aws.String("192.168.0.2")}, 592 } 593 594 result := flattenNetworkInterfacesPrivateIPAddresses(expanded) 595 596 if result == nil { 597 t.Fatal("result was nil") 598 } 599 600 if len(result) != 2 { 601 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 602 } 603 604 if result[0] != "192.168.0.1" { 605 t.Fatalf("expected ip to be 192.168.0.1, but was %s", result[0]) 606 } 607 608 if result[1] != "192.168.0.2" { 609 t.Fatalf("expected ip to be 192.168.0.2, but was %s", result[1]) 610 } 611 } 612 613 func TestFlattenGroupIdentifiers(t *testing.T) { 614 expanded := []*ec2.GroupIdentifier{ 615 &ec2.GroupIdentifier{GroupId: aws.String("sg-001")}, 616 &ec2.GroupIdentifier{GroupId: aws.String("sg-002")}, 617 } 618 619 result := flattenGroupIdentifiers(expanded) 620 621 if len(result) != 2 { 622 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 623 } 624 625 if result[0] != "sg-001" { 626 t.Fatalf("expected id to be sg-001, but was %s", result[0]) 627 } 628 629 if result[1] != "sg-002" { 630 t.Fatalf("expected id to be sg-002, but was %s", result[1]) 631 } 632 } 633 634 func TestExpandPrivateIPAddresses(t *testing.T) { 635 636 ip1 := "192.168.0.1" 637 ip2 := "192.168.0.2" 638 flattened := []interface{}{ 639 ip1, 640 ip2, 641 } 642 643 result := expandPrivateIPAddresses(flattened) 644 645 if len(result) != 2 { 646 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 647 } 648 649 if *result[0].PrivateIpAddress != "192.168.0.1" || !*result[0].Primary { 650 t.Fatalf("expected ip to be 192.168.0.1 and Primary, but got %v, %t", *result[0].PrivateIpAddress, *result[0].Primary) 651 } 652 653 if *result[1].PrivateIpAddress != "192.168.0.2" || *result[1].Primary { 654 t.Fatalf("expected ip to be 192.168.0.2 and not Primary, but got %v, %t", *result[1].PrivateIpAddress, *result[1].Primary) 655 } 656 } 657 658 func TestFlattenAttachment(t *testing.T) { 659 expanded := &ec2.NetworkInterfaceAttachment{ 660 InstanceId: aws.String("i-00001"), 661 DeviceIndex: aws.Int64(int64(1)), 662 AttachmentId: aws.String("at-002"), 663 } 664 665 result := flattenAttachment(expanded) 666 667 if result == nil { 668 t.Fatal("expected result to have value, but got nil") 669 } 670 671 if result["instance"] != "i-00001" { 672 t.Fatalf("expected instance to be i-00001, but got %s", result["instance"]) 673 } 674 675 if result["device_index"] != int64(1) { 676 t.Fatalf("expected device_index to be 1, but got %d", result["device_index"]) 677 } 678 679 if result["attachment_id"] != "at-002" { 680 t.Fatalf("expected attachment_id to be at-002, but got %s", result["attachment_id"]) 681 } 682 } 683 684 func TestFlattenResourceRecords(t *testing.T) { 685 expanded := []*route53.ResourceRecord{ 686 &route53.ResourceRecord{ 687 Value: aws.String("127.0.0.1"), 688 }, 689 &route53.ResourceRecord{ 690 Value: aws.String("127.0.0.3"), 691 }, 692 } 693 694 result := flattenResourceRecords(expanded) 695 696 if result == nil { 697 t.Fatal("expected result to have value, but got nil") 698 } 699 700 if len(result) != 2 { 701 t.Fatal("expected result to have value, but got nil") 702 } 703 } 704 705 func TestFlattenAsgEnabledMetrics(t *testing.T) { 706 expanded := []*autoscaling.EnabledMetric{ 707 &autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupTotalInstances")}, 708 &autoscaling.EnabledMetric{Granularity: aws.String("1Minute"), Metric: aws.String("GroupMaxSize")}, 709 } 710 711 result := flattenAsgEnabledMetrics(expanded) 712 713 if len(result) != 2 { 714 t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) 715 } 716 717 if result[0] != "GroupTotalInstances" { 718 t.Fatalf("expected id to be GroupTotalInstances, but was %s", result[0]) 719 } 720 721 if result[1] != "GroupMaxSize" { 722 t.Fatalf("expected id to be GroupMaxSize, but was %s", result[1]) 723 } 724 }