From 6376ac2dab1cf6429eff70024dc0e71cad244475 Mon Sep 17 00:00:00 2001 From: Clint Shryock Date: Tue, 7 Apr 2015 12:07:12 -0500 Subject: [PATCH] provider/aws: Convert AWS Network Interface to aws-sdk-go Also adds sdk versions of structure, structure test --- .../aws/resource_aws_network_interface.go | 71 ++- .../resource_aws_network_interface_test.go | 34 +- builtin/providers/aws/structure_sdk.go | 253 ++++++++++ builtin/providers/aws/structure_test_sdk.go | 444 ++++++++++++++++++ 4 files changed, 755 insertions(+), 47 deletions(-) create mode 100644 builtin/providers/aws/structure_sdk.go create mode 100644 builtin/providers/aws/structure_test_sdk.go diff --git a/builtin/providers/aws/resource_aws_network_interface.go b/builtin/providers/aws/resource_aws_network_interface.go index 242e0d80c6..aebe635913 100644 --- a/builtin/providers/aws/resource_aws_network_interface.go +++ b/builtin/providers/aws/resource_aws_network_interface.go @@ -7,8 +7,8 @@ import ( "strconv" "time" - "github.com/hashicorp/aws-sdk-go/aws" - "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/awslabs/aws-sdk-go/aws" + "github.com/awslabs/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -78,33 +78,32 @@ func resourceAwsNetworkInterface() *schema.Resource { func resourceAwsNetworkInterfaceCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn - request := &ec2.CreateNetworkInterfaceRequest{ - Groups: expandStringList(d.Get("security_groups").(*schema.Set).List()), + request := &ec2.CreateNetworkInterfaceInput{ + Groups: expandStringListSDK(d.Get("security_groups").(*schema.Set).List()), SubnetID: aws.String(d.Get("subnet_id").(string)), - PrivateIPAddresses: expandPrivateIPAddesses(d.Get("private_ips").(*schema.Set).List()), + PrivateIPAddresses: expandPrivateIPAddessesSDK(d.Get("private_ips").(*schema.Set).List()), } log.Printf("[DEBUG] Creating network interface") - resp, err := ec2conn.CreateNetworkInterface(request) + resp, err := conn.CreateNetworkInterface(request) if err != nil { return fmt.Errorf("Error creating ENI: %s", err) } d.SetId(*resp.NetworkInterface.NetworkInterfaceID) log.Printf("[INFO] ENI ID: %s", d.Id()) - return resourceAwsNetworkInterfaceUpdate(d, meta) } func resourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn - describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesRequest{ - NetworkInterfaceIDs: []string{d.Id()}, + conn := meta.(*AWSClient).ec2SDKconn + describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesInput{ + NetworkInterfaceIDs: []*string{aws.String(d.Id())}, } - describeResp, err := ec2conn.DescribeNetworkInterfaces(describe_network_interfaces_request) + describeResp, err := conn.DescribeNetworkInterfaces(describe_network_interfaces_request) if err != nil { if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidNetworkInterfaceID.NotFound" { @@ -121,14 +120,14 @@ func resourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e eni := describeResp.NetworkInterfaces[0] d.Set("subnet_id", eni.SubnetID) - d.Set("private_ips", flattenNetworkInterfacesPrivateIPAddesses(eni.PrivateIPAddresses)) - d.Set("security_groups", flattenGroupIdentifiers(eni.Groups)) + d.Set("private_ips", flattenNetworkInterfacesPrivateIPAddessesSDK(eni.PrivateIPAddresses)) + d.Set("security_groups", flattenGroupIdentifiersSDK(eni.Groups)) // Tags - d.Set("tags", tagsToMap(eni.TagSet)) + d.Set("tags", tagsToMapSDK(eni.TagSet)) if eni.Attachment != nil { - attachment := []map[string]interface{}{flattenAttachment(eni.Attachment)} + attachment := []map[string]interface{}{flattenAttachmentSDK(eni.Attachment)} d.Set("attachment", attachment) } else { d.Set("attachment", nil) @@ -137,13 +136,13 @@ func resourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e return nil } -func networkInterfaceAttachmentRefreshFunc(ec2conn *ec2.EC2, id string) resource.StateRefreshFunc { +func networkInterfaceAttachmentRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesRequest{ - NetworkInterfaceIDs: []string{id}, + describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesInput{ + NetworkInterfaceIDs: []*string{aws.String(id)}, } - describeResp, err := ec2conn.DescribeNetworkInterfaces(describe_network_interfaces_request) + describeResp, err := conn.DescribeNetworkInterfaces(describe_network_interfaces_request) if err != nil { log.Printf("[ERROR] Could not find network interface %s. %s", id, err) @@ -161,12 +160,12 @@ func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId s // if there was an old attachment, remove it if oa != nil && len(oa.List()) > 0 { old_attachment := oa.List()[0].(map[string]interface{}) - detach_request := &ec2.DetachNetworkInterfaceRequest{ + detach_request := &ec2.DetachNetworkInterfaceInput{ AttachmentID: aws.String(old_attachment["attachment_id"].(string)), Force: aws.Boolean(true), } - ec2conn := meta.(*AWSClient).ec2conn - detach_err := ec2conn.DetachNetworkInterface(detach_request) + conn := meta.(*AWSClient).ec2SDKconn + _, detach_err := conn.DetachNetworkInterface(detach_request) if detach_err != nil { return fmt.Errorf("Error detaching ENI: %s", detach_err) } @@ -175,7 +174,7 @@ func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId s stateConf := &resource.StateChangeConf{ Pending: []string{"true"}, Target: "false", - Refresh: networkInterfaceAttachmentRefreshFunc(ec2conn, eniId), + Refresh: networkInterfaceAttachmentRefreshFunc(conn, eniId), Timeout: 10 * time.Minute, } if _, err := stateConf.WaitForState(); err != nil { @@ -188,11 +187,10 @@ func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId s } func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn d.Partial(true) if d.HasChange("attachment") { - ec2conn := meta.(*AWSClient).ec2conn oa, na := d.GetChange("attachment") detach_err := resourceAwsNetworkInterfaceDetach(oa.(*schema.Set), meta, d.Id()) @@ -203,12 +201,13 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) // if there is a new attachment, attach it if na != nil && len(na.(*schema.Set).List()) > 0 { new_attachment := na.(*schema.Set).List()[0].(map[string]interface{}) - attach_request := &ec2.AttachNetworkInterfaceRequest{ - DeviceIndex: aws.Integer(new_attachment["device_index"].(int)), + di := new_attachment["device_index"].(int) + attach_request := &ec2.AttachNetworkInterfaceInput{ + DeviceIndex: aws.Long(int64(di)), InstanceID: aws.String(new_attachment["instance"].(string)), NetworkInterfaceID: aws.String(d.Id()), } - _, attach_err := ec2conn.AttachNetworkInterface(attach_request) + _, attach_err := conn.AttachNetworkInterface(attach_request) if attach_err != nil { return fmt.Errorf("Error attaching ENI: %s", attach_err) } @@ -218,12 +217,12 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) } if d.HasChange("security_groups") { - request := &ec2.ModifyNetworkInterfaceAttributeRequest{ + request := &ec2.ModifyNetworkInterfaceAttributeInput{ NetworkInterfaceID: aws.String(d.Id()), - Groups: expandStringList(d.Get("security_groups").(*schema.Set).List()), + Groups: expandStringListSDK(d.Get("security_groups").(*schema.Set).List()), } - err := ec2conn.ModifyNetworkInterfaceAttribute(request) + _, err := conn.ModifyNetworkInterfaceAttribute(request) if err != nil { return fmt.Errorf("Failure updating ENI: %s", err) } @@ -231,7 +230,7 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) d.SetPartial("security_groups") } - if err := setTags(ec2conn, d); err != nil { + if err := setTagsSDK(conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -243,7 +242,7 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) } func resourceAwsNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).ec2conn + conn := meta.(*AWSClient).ec2SDKconn log.Printf("[INFO] Deleting ENI: %s", d.Id()) @@ -252,10 +251,10 @@ func resourceAwsNetworkInterfaceDelete(d *schema.ResourceData, meta interface{}) return detach_err } - deleteEniOpts := ec2.DeleteNetworkInterfaceRequest{ + deleteEniOpts := ec2.DeleteNetworkInterfaceInput{ NetworkInterfaceID: aws.String(d.Id()), } - if err := ec2conn.DeleteNetworkInterface(&deleteEniOpts); err != nil { + if _, err := conn.DeleteNetworkInterface(&deleteEniOpts); err != nil { return fmt.Errorf("Error deleting ENI: %s", err) } diff --git a/builtin/providers/aws/resource_aws_network_interface_test.go b/builtin/providers/aws/resource_aws_network_interface_test.go index 5c65cfa0c3..0f486df0b3 100644 --- a/builtin/providers/aws/resource_aws_network_interface_test.go +++ b/builtin/providers/aws/resource_aws_network_interface_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/aws-sdk-go/aws" - "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/awslabs/aws-sdk-go/aws" + "github.com/awslabs/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) @@ -67,11 +67,11 @@ func testAccCheckAWSENIExists(n string, res *ec2.NetworkInterface) resource.Test return fmt.Errorf("No ENI ID is set") } - ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn - describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesRequest{ - NetworkInterfaceIDs: []string{rs.Primary.ID}, + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn + describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesInput{ + NetworkInterfaceIDs: []*string{aws.String(rs.Primary.ID)}, } - describeResp, err := ec2conn.DescribeNetworkInterfaces(describe_network_interfaces_request) + describeResp, err := conn.DescribeNetworkInterfaces(describe_network_interfaces_request) if err != nil { return err @@ -82,7 +82,7 @@ func testAccCheckAWSENIExists(n string, res *ec2.NetworkInterface) resource.Test return fmt.Errorf("ENI not found") } - *res = describeResp.NetworkInterfaces[0] + *res = *describeResp.NetworkInterfaces[0] return nil } @@ -148,11 +148,11 @@ func testAccCheckAWSENIDestroy(s *terraform.State) error { continue } - ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn - describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesRequest{ - NetworkInterfaceIDs: []string{rs.Primary.ID}, + conn := testAccProvider.Meta().(*AWSClient).ec2SDKconn + describe_network_interfaces_request := &ec2.DescribeNetworkInterfacesInput{ + NetworkInterfaceIDs: []*string{aws.String(rs.Primary.ID)}, } - _, err := ec2conn.DescribeNetworkInterfaces(describe_network_interfaces_request) + _, err := conn.DescribeNetworkInterfaces(describe_network_interfaces_request) if err != nil { if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidNetworkInterfaceID.NotFound" { @@ -196,18 +196,27 @@ resource "aws_network_interface" "bar" { const testAccAWSENIConfigWithAttachment = ` resource "aws_vpc" "foo" { cidr_block = "172.16.0.0/16" + tags { + Name = "tf-eni-test" + } } resource "aws_subnet" "foo" { vpc_id = "${aws_vpc.foo.id}" cidr_block = "172.16.10.0/24" availability_zone = "us-west-2a" + tags { + Name = "tf-eni-test" + } } resource "aws_subnet" "bar" { vpc_id = "${aws_vpc.foo.id}" cidr_block = "172.16.11.0/24" availability_zone = "us-west-2a" + tags { + Name = "tf-eni-test" + } } resource "aws_security_group" "foo" { @@ -222,6 +231,9 @@ resource "aws_instance" "foo" { subnet_id = "${aws_subnet.bar.id}" associate_public_ip_address = false private_ip = "172.16.11.50" + tags { + Name = "tf-eni-test" + } } resource "aws_network_interface" "bar" { diff --git a/builtin/providers/aws/structure_sdk.go b/builtin/providers/aws/structure_sdk.go new file mode 100644 index 0000000000..8a7fdaef67 --- /dev/null +++ b/builtin/providers/aws/structure_sdk.go @@ -0,0 +1,253 @@ +package aws + +import ( + "strings" + + "github.com/awslabs/aws-sdk-go/service/ec2" + "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/gen/elb" + "github.com/hashicorp/aws-sdk-go/gen/rds" + "github.com/hashicorp/terraform/helper/schema" +) + +// Takes the result of flatmap.Expand for an array of listeners and +// returns ELB API compatible objects +func expandListenersSDK(configured []interface{}) ([]elb.Listener, error) { + listeners := make([]elb.Listener, 0, len(configured)) + + // Loop over our configured listeners and create + // an array of aws-sdk-go compatabile objects + for _, lRaw := range configured { + data := lRaw.(map[string]interface{}) + + l := elb.Listener{ + InstancePort: aws.Integer(data["instance_port"].(int)), + InstanceProtocol: aws.String(data["instance_protocol"].(string)), + LoadBalancerPort: aws.Integer(data["lb_port"].(int)), + Protocol: aws.String(data["lb_protocol"].(string)), + } + + if v, ok := data["ssl_certificate_id"]; ok { + l.SSLCertificateID = aws.String(v.(string)) + } + + listeners = append(listeners, l) + } + + return listeners, nil +} + +// Takes the result of flatmap.Expand for an array of ingress/egress +// security group rules and returns EC2 API compatible objects +func expandIPPermsSDK( + group ec2.SecurityGroup, configured []interface{}) []*ec2.IPPermission { + vpc := group.VPCID != nil + + perms := make([]*ec2.IPPermission, len(configured)) + for i, mRaw := range configured { + var perm ec2.IPPermission + m := mRaw.(map[string]interface{}) + + perm.FromPort = aws.Long(m["from_port"].(int64)) + perm.ToPort = aws.Long(m["to_port"].(int64)) + perm.IPProtocol = aws.String(m["protocol"].(string)) + + var groups []string + if raw, ok := m["security_groups"]; ok { + list := raw.(*schema.Set).List() + for _, v := range list { + groups = append(groups, v.(string)) + } + } + if v, ok := m["self"]; ok && v.(bool) { + if vpc { + groups = append(groups, *group.GroupID) + } else { + groups = append(groups, *group.GroupName) + } + } + + if len(groups) > 0 { + perm.UserIDGroupPairs = make([]*ec2.UserIDGroupPair, len(groups)) + for i, name := range groups { + ownerId, id := "", name + if items := strings.Split(id, "/"); len(items) > 1 { + ownerId, id = items[0], items[1] + } + + perm.UserIDGroupPairs[i] = &ec2.UserIDGroupPair{ + GroupID: aws.String(id), + UserID: aws.String(ownerId), + } + if !vpc { + perm.UserIDGroupPairs[i].GroupID = nil + perm.UserIDGroupPairs[i].GroupName = aws.String(id) + perm.UserIDGroupPairs[i].UserID = nil + } + } + } + + if raw, ok := m["cidr_blocks"]; ok { + list := raw.([]interface{}) + perm.IPRanges = make([]*ec2.IPRange, len(list)) + for i, v := range list { + perm.IPRanges[i] = &ec2.IPRange{CIDRIP: aws.String(v.(string))} + } + } + + perms[i] = &perm + } + + return perms +} + +// Takes the result of flatmap.Expand for an array of parameters and +// returns Parameter API compatible objects +func expandParametersSDK(configured []interface{}) ([]rds.Parameter, error) { + parameters := make([]rds.Parameter, 0, len(configured)) + + // Loop over our configured parameters and create + // an array of aws-sdk-go compatabile objects + for _, pRaw := range configured { + data := pRaw.(map[string]interface{}) + + p := rds.Parameter{ + ApplyMethod: aws.String(data["apply_method"].(string)), + ParameterName: aws.String(data["name"].(string)), + ParameterValue: aws.String(data["value"].(string)), + } + + parameters = append(parameters, p) + } + + return parameters, nil +} + +// Flattens a health check into something that flatmap.Flatten() +// can handle +func flattenHealthCheckSDK(check *elb.HealthCheck) []map[string]interface{} { + result := make([]map[string]interface{}, 0, 1) + + chk := make(map[string]interface{}) + chk["unhealthy_threshold"] = *check.UnhealthyThreshold + chk["healthy_threshold"] = *check.HealthyThreshold + chk["target"] = *check.Target + chk["timeout"] = *check.Timeout + chk["interval"] = *check.Interval + + result = append(result, chk) + + return result +} + +// Flattens an array of UserSecurityGroups into a []string +func flattenSecurityGroupsSDK(list []ec2.UserIDGroupPair) []string { + result := make([]string, 0, len(list)) + for _, g := range list { + result = append(result, *g.GroupID) + } + return result +} + +// Flattens an array of Instances into a []string +func flattenInstancesSDK(list []elb.Instance) []string { + result := make([]string, 0, len(list)) + for _, i := range list { + result = append(result, *i.InstanceID) + } + return result +} + +// Expands an array of String Instance IDs into a []Instances +func expandInstanceStringSDK(list []interface{}) []elb.Instance { + result := make([]elb.Instance, 0, len(list)) + for _, i := range list { + result = append(result, elb.Instance{aws.String(i.(string))}) + } + return result +} + +// Flattens an array of Listeners into a []map[string]interface{} +func flattenListenersSDK(list []elb.ListenerDescription) []map[string]interface{} { + result := make([]map[string]interface{}, 0, len(list)) + for _, i := range list { + l := map[string]interface{}{ + "instance_port": *i.Listener.InstancePort, + "instance_protocol": strings.ToLower(*i.Listener.InstanceProtocol), + "lb_port": *i.Listener.LoadBalancerPort, + "lb_protocol": strings.ToLower(*i.Listener.Protocol), + } + // SSLCertificateID is optional, and may be nil + if i.Listener.SSLCertificateID != nil { + l["ssl_certificate_id"] = *i.Listener.SSLCertificateID + } + result = append(result, l) + } + return result +} + +// Flattens an array of Parameters into a []map[string]interface{} +func flattenParametersSDK(list []rds.Parameter) []map[string]interface{} { + result := make([]map[string]interface{}, 0, len(list)) + for _, i := range list { + result = append(result, map[string]interface{}{ + "name": strings.ToLower(*i.ParameterName), + "value": strings.ToLower(*i.ParameterValue), + }) + } + return result +} + +// Takes the result of flatmap.Expand for an array of strings +// and returns a []string +func expandStringListSDK(configured []interface{}) []*string { + vs := make([]*string, 0, len(configured)) + for _, v := range configured { + vs = append(vs, aws.String(v.(string))) + } + return vs +} + +//Flattens an array of private ip addresses into a []string, where the elements returned are the IP strings e.g. "192.168.0.0" +func flattenNetworkInterfacesPrivateIPAddessesSDK(dtos []*ec2.NetworkInterfacePrivateIPAddress) []string { + ips := make([]string, 0, len(dtos)) + for _, v := range dtos { + ip := *v.PrivateIPAddress + ips = append(ips, ip) + } + return ips +} + +//Flattens security group identifiers into a []string, where the elements returned are the GroupIDs +func flattenGroupIdentifiersSDK(dtos []*ec2.GroupIdentifier) []string { + ids := make([]string, 0, len(dtos)) + for _, v := range dtos { + group_id := *v.GroupID + ids = append(ids, group_id) + } + return ids +} + +//Expands an array of IPs into a ec2 Private IP Address Spec +func expandPrivateIPAddessesSDK(ips []interface{}) []*ec2.PrivateIPAddressSpecification { + dtos := make([]*ec2.PrivateIPAddressSpecification, 0, len(ips)) + for i, v := range ips { + new_private_ip := &ec2.PrivateIPAddressSpecification{ + PrivateIPAddress: aws.String(v.(string)), + } + + new_private_ip.Primary = aws.Boolean(i == 0) + + dtos = append(dtos, new_private_ip) + } + return dtos +} + +//Flattens network interface attachment into a map[string]interface +func flattenAttachmentSDK(a *ec2.NetworkInterfaceAttachment) map[string]interface{} { + att := make(map[string]interface{}) + att["instance"] = *a.InstanceID + att["device_index"] = *a.DeviceIndex + att["attachment_id"] = *a.AttachmentID + return att +} diff --git a/builtin/providers/aws/structure_test_sdk.go b/builtin/providers/aws/structure_test_sdk.go new file mode 100644 index 0000000000..9e196d1f4d --- /dev/null +++ b/builtin/providers/aws/structure_test_sdk.go @@ -0,0 +1,444 @@ +package aws + +import ( + "reflect" + "testing" + + "github.com/awslabs/aws-sdk-go/service/ec2" + "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/gen/elb" + "github.com/hashicorp/aws-sdk-go/gen/rds" + "github.com/hashicorp/terraform/flatmap" + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" +) + +// Returns test configuration +// func testConf() map[string]string { +// return map[string]string{ +// "listener.#": "1", +// "listener.0.lb_port": "80", +// "listener.0.lb_protocol": "http", +// "listener.0.instance_port": "8000", +// "listener.0.instance_protocol": "http", +// "availability_zones.#": "2", +// "availability_zones.0": "us-east-1a", +// "availability_zones.1": "us-east-1b", +// "ingress.#": "1", +// "ingress.0.protocol": "icmp", +// "ingress.0.from_port": "1", +// "ingress.0.to_port": "-1", +// "ingress.0.cidr_blocks.#": "1", +// "ingress.0.cidr_blocks.0": "0.0.0.0/0", +// "ingress.0.security_groups.#": "2", +// "ingress.0.security_groups.0": "sg-11111", +// "ingress.0.security_groups.1": "foo/sg-22222", +// } +// } + +func TestExpandIPPermsSDK(t *testing.T) { + hash := func(v interface{}) int { + return hashcode.String(v.(string)) + } + + expanded := []interface{}{ + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "cidr_blocks": []interface{}{"0.0.0.0/0"}, + "security_groups": schema.NewSet(hash, []interface{}{ + "sg-11111", + "foo/sg-22222", + }), + }, + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "self": true, + }, + } + group := ec2.SecurityGroup{ + GroupID: aws.String("foo"), + VPCID: aws.String("bar"), + } + perms := expandIPPermsSDK(group, expanded) + + expected := []ec2.IPPermission{ + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Long(1), + ToPort: aws.Long(-1), + IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}}, + UserIDGroupPairs: []*ec2.UserIDGroupPair{ + &ec2.UserIDGroupPair{ + UserID: aws.String("foo"), + GroupID: aws.String("sg-22222"), + }, + &ec2.UserIDGroupPair{ + GroupID: aws.String("sg-22222"), + }, + }, + }, + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Long(1), + ToPort: aws.Long(-1), + UserIDGroupPairs: []*ec2.UserIDGroupPair{ + &ec2.UserIDGroupPair{ + UserID: aws.String("foo"), + }, + }, + }, + } + + exp := expected[0] + perm := perms[0] + + if *exp.FromPort != *perm.FromPort { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.FromPort, + *exp.FromPort) + } + + if *exp.IPRanges[0].CIDRIP != *perm.IPRanges[0].CIDRIP { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.IPRanges[0].CIDRIP, + *exp.IPRanges[0].CIDRIP) + } + + if *exp.UserIDGroupPairs[0].UserID != *perm.UserIDGroupPairs[0].UserID { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.UserIDGroupPairs[0].UserID, + *exp.UserIDGroupPairs[0].UserID) + } + +} + +func TestExpandIPPerms_nonVPCSDK(t *testing.T) { + hash := func(v interface{}) int { + return hashcode.String(v.(string)) + } + + expanded := []interface{}{ + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "cidr_blocks": []interface{}{"0.0.0.0/0"}, + "security_groups": schema.NewSet(hash, []interface{}{ + "sg-11111", + "foo/sg-22222", + }), + }, + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "self": true, + }, + } + group := ec2.SecurityGroup{ + GroupName: aws.String("foo"), + } + perms := expandIPPermsSDK(group, expanded) + + expected := []ec2.IPPermission{ + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Long(1), + ToPort: aws.Long(-1), + IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}}, + UserIDGroupPairs: []*ec2.UserIDGroupPair{ + &ec2.UserIDGroupPair{ + GroupName: aws.String("sg-22222"), + }, + &ec2.UserIDGroupPair{ + GroupName: aws.String("sg-22222"), + }, + }, + }, + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Long(1), + ToPort: aws.Long(-1), + UserIDGroupPairs: []*ec2.UserIDGroupPair{ + &ec2.UserIDGroupPair{ + GroupName: aws.String("foo"), + }, + }, + }, + } + + exp := expected[0] + perm := perms[0] + + if *exp.FromPort != *perm.FromPort { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.FromPort, + *exp.FromPort) + } + + if *exp.IPRanges[0].CIDRIP != *perm.IPRanges[0].CIDRIP { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.IPRanges[0].CIDRIP, + *exp.IPRanges[0].CIDRIP) + } +} + +func TestExpandListenersSDK(t *testing.T) { + expanded := []interface{}{ + map[string]interface{}{ + "instance_port": 8000, + "lb_port": 80, + "instance_protocol": "http", + "lb_protocol": "http", + }, + } + listeners, err := expandListenersSDK(expanded) + if err != nil { + t.Fatalf("bad: %#v", err) + } + + expected := elb.Listener{ + InstancePort: aws.Integer(8000), + LoadBalancerPort: aws.Integer(80), + InstanceProtocol: aws.String("http"), + Protocol: aws.String("http"), + } + + if !reflect.DeepEqual(listeners[0], expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + listeners[0], + expected) + } + +} + +func TestFlattenHealthCheckSDK(t *testing.T) { + cases := []struct { + Input elb.HealthCheck + Output []map[string]interface{} + }{ + { + Input: elb.HealthCheck{ + UnhealthyThreshold: aws.Integer(10), + HealthyThreshold: aws.Integer(10), + Target: aws.String("HTTP:80/"), + Timeout: aws.Integer(30), + Interval: aws.Integer(30), + }, + Output: []map[string]interface{}{ + map[string]interface{}{ + "unhealthy_threshold": 10, + "healthy_threshold": 10, + "target": "HTTP:80/", + "timeout": 30, + "interval": 30, + }, + }, + }, + } + + for _, tc := range cases { + output := flattenHealthCheckSDK(&tc.Input) + if !reflect.DeepEqual(output, tc.Output) { + t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) + } + } +} + +func TestExpandStringListSDK(t *testing.T) { + expanded := flatmap.Expand(testConf(), "availability_zones").([]interface{}) + stringList := expandStringList(expanded) + expected := []string{ + "us-east-1a", + "us-east-1b", + } + + if !reflect.DeepEqual(stringList, expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + stringList, + expected) + } + +} + +func TestExpandParametersSDK(t *testing.T) { + expanded := []interface{}{ + map[string]interface{}{ + "name": "character_set_client", + "value": "utf8", + "apply_method": "immediate", + }, + } + parameters, err := expandParametersSDK(expanded) + if err != nil { + t.Fatalf("bad: %#v", err) + } + + expected := rds.Parameter{ + ParameterName: aws.String("character_set_client"), + ParameterValue: aws.String("utf8"), + ApplyMethod: aws.String("immediate"), + } + + if !reflect.DeepEqual(parameters[0], expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + parameters[0], + expected) + } +} + +func TestFlattenParametersSDK(t *testing.T) { + cases := []struct { + Input []rds.Parameter + Output []map[string]interface{} + }{ + { + Input: []rds.Parameter{ + rds.Parameter{ + ParameterName: aws.String("character_set_client"), + ParameterValue: aws.String("utf8"), + }, + }, + Output: []map[string]interface{}{ + map[string]interface{}{ + "name": "character_set_client", + "value": "utf8", + }, + }, + }, + } + + for _, tc := range cases { + output := flattenParametersSDK(tc.Input) + if !reflect.DeepEqual(output, tc.Output) { + t.Fatalf("Got:\n\n%#v\n\nExpected:\n\n%#v", output, tc.Output) + } + } +} + +func TestExpandInstanceStringSDK(t *testing.T) { + + expected := []elb.Instance{ + elb.Instance{aws.String("test-one")}, + elb.Instance{aws.String("test-two")}, + } + + ids := []interface{}{ + "test-one", + "test-two", + } + + expanded := expandInstanceStringSDK(ids) + + if !reflect.DeepEqual(expanded, expected) { + t.Fatalf("Expand Instance String output did not match.\nGot:\n%#v\n\nexpected:\n%#v", expanded, expected) + } +} + +func TestFlattenNetworkInterfacesPrivateIPAddessesSDK(t *testing.T) { + expanded := []*ec2.NetworkInterfacePrivateIPAddress{ + &ec2.NetworkInterfacePrivateIPAddress{PrivateIPAddress: aws.String("192.168.0.1")}, + &ec2.NetworkInterfacePrivateIPAddress{PrivateIPAddress: aws.String("192.168.0.2")}, + } + + result := flattenNetworkInterfacesPrivateIPAddessesSDK(expanded) + + if result == nil { + t.Fatal("result was nil") + } + + if len(result) != 2 { + t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) + } + + if result[0] != "192.168.0.1" { + t.Fatalf("expected ip to be 192.168.0.1, but was %s", result[0]) + } + + if result[1] != "192.168.0.2" { + t.Fatalf("expected ip to be 192.168.0.2, but was %s", result[1]) + } +} + +func TestFlattenGroupIdentifiersSDK(t *testing.T) { + expanded := []*ec2.GroupIdentifier{ + &ec2.GroupIdentifier{GroupID: aws.String("sg-001")}, + &ec2.GroupIdentifier{GroupID: aws.String("sg-002")}, + } + + result := flattenGroupIdentifiersSDK(expanded) + + if len(result) != 2 { + t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) + } + + if result[0] != "sg-001" { + t.Fatalf("expected id to be sg-001, but was %s", result[0]) + } + + if result[1] != "sg-002" { + t.Fatalf("expected id to be sg-002, but was %s", result[1]) + } +} + +func TestExpandPrivateIPAddessesSDK(t *testing.T) { + + ip1 := "192.168.0.1" + ip2 := "192.168.0.2" + flattened := []interface{}{ + ip1, + ip2, + } + + result := expandPrivateIPAddessesSDK(flattened) + + if len(result) != 2 { + t.Fatalf("expected result had %d elements, but got %d", 2, len(result)) + } + + if *result[0].PrivateIPAddress != "192.168.0.1" || !*result[0].Primary { + t.Fatalf("expected ip to be 192.168.0.1 and Primary, but got %v, %t", *result[0].PrivateIPAddress, *result[0].Primary) + } + + if *result[1].PrivateIPAddress != "192.168.0.2" || *result[1].Primary { + t.Fatalf("expected ip to be 192.168.0.2 and not Primary, but got %v, %t", *result[1].PrivateIPAddress, *result[1].Primary) + } +} + +func TestFlattenAttachmentSDK(t *testing.T) { + expanded := &ec2.NetworkInterfaceAttachment{ + InstanceID: aws.String("i-00001"), + DeviceIndex: aws.Long(1), + AttachmentID: aws.String("at-002"), + } + + result := flattenAttachmentSDK(expanded) + + if result == nil { + t.Fatal("expected result to have value, but got nil") + } + + if result["instance"] != "i-00001" { + t.Fatalf("expected instance to be i-00001, but got %s", result["instance"]) + } + + if result["device_index"] != 1 { + t.Fatalf("expected device_index to be 1, but got %d", result["device_index"]) + } + + if result["attachment_id"] != "at-002" { + t.Fatalf("expected attachment_id to be at-002, but got %s", result["attachment_id"]) + } +}