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