Merge pull request #1191 from hashicorp/rmenn-aws-go-vpc

provider/aws: Convert AWS VPC to aws-sdk-go
This commit is contained in:
Clint 2015-03-12 16:19:39 -05:00
commit 96c41de946
2 changed files with 127 additions and 70 deletions

View File

@ -5,9 +5,10 @@ import (
"log" "log"
"time" "time"
"github.com/hashicorp/aws-sdk-go/aws"
"github.com/hashicorp/aws-sdk-go/gen/ec2"
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/mitchellh/goamz/ec2"
) )
func resourceAwsVpc() *schema.Resource { func resourceAwsVpc() *schema.Resource {
@ -63,23 +64,26 @@ func resourceAwsVpc() *schema.Resource {
} }
func resourceAwsVpcCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsVpcCreate(d *schema.ResourceData, meta interface{}) error {
ec2conn := meta.(*AWSClient).ec2conn ec2conn := meta.(*AWSClient).awsEC2conn
instance_tenancy := "default"
// Create the VPC if v, ok := d.GetOk("instance_tenancy"); ok {
createOpts := &ec2.CreateVpc{ instance_tenancy = v.(string)
CidrBlock: d.Get("cidr_block").(string),
InstanceTenancy: d.Get("instance_tenancy").(string),
} }
log.Printf("[DEBUG] VPC create config: %#v", createOpts) // Create the VPC
vpcResp, err := ec2conn.CreateVpc(createOpts) createOpts := &ec2.CreateVPCRequest{
CIDRBlock: aws.String(d.Get("cidr_block").(string)),
InstanceTenancy: aws.String(instance_tenancy),
}
log.Printf("[DEBUG] VPC create config: %#v", *createOpts)
vpcResp, err := ec2conn.CreateVPC(createOpts)
if err != nil { if err != nil {
return fmt.Errorf("Error creating VPC: %s", err) return fmt.Errorf("Error creating VPC: %s", err)
} }
// Get the ID and store it // Get the ID and store it
vpc := &vpcResp.VPC vpc := vpcResp.VPC
log.Printf("[INFO] VPC ID: %s", vpc.VpcId) d.SetId(*vpc.VPCID)
d.SetId(vpc.VpcId) log.Printf("[INFO] VPC ID: %s", d.Id())
// Set partial mode and say that we setup the cidr block // Set partial mode and say that we setup the cidr block
d.Partial(true) d.Partial(true)
@ -106,7 +110,7 @@ func resourceAwsVpcCreate(d *schema.ResourceData, meta interface{}) error {
} }
func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error { func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error {
ec2conn := meta.(*AWSClient).ec2conn ec2conn := meta.(*AWSClient).awsEC2conn
// Refresh the VPC state // Refresh the VPC state
vpcRaw, _, err := VPCStateRefreshFunc(ec2conn, d.Id())() vpcRaw, _, err := VPCStateRefreshFunc(ec2conn, d.Id())()
@ -120,34 +124,53 @@ func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error {
// VPC stuff // VPC stuff
vpc := vpcRaw.(*ec2.VPC) vpc := vpcRaw.(*ec2.VPC)
d.Set("cidr_block", vpc.CidrBlock) vpcid := d.Id()
d.Set("cidr_block", vpc.CIDRBlock)
// Tags // Tags
d.Set("tags", tagsToMap(vpc.Tags)) d.Set("tags", tagsToMapSDK(vpc.Tags))
// Attributes // Attributes
resp, err := ec2conn.VpcAttribute(d.Id(), "enableDnsSupport") attribute := "enableDnsSupport"
DescribeAttrOpts := &ec2.DescribeVPCAttributeRequest{
Attribute: aws.String(attribute),
VPCID: aws.String(vpcid),
}
resp, err := ec2conn.DescribeVPCAttribute(DescribeAttrOpts)
if err != nil { if err != nil {
return err return err
} }
d.Set("enable_dns_support", resp.EnableDnsSupport) d.Set("enable_dns_support", *resp.EnableDNSSupport)
attribute = "enableDnsHostnames"
resp, err = ec2conn.VpcAttribute(d.Id(), "enableDnsHostnames") DescribeAttrOpts = &ec2.DescribeVPCAttributeRequest{
Attribute: &attribute,
VPCID: &vpcid,
}
resp, err = ec2conn.DescribeVPCAttribute(DescribeAttrOpts)
if err != nil { if err != nil {
return err return err
} }
d.Set("enable_dns_hostnames", resp.EnableDnsHostnames) d.Set("enable_dns_hostnames", *resp.EnableDNSHostnames)
// Get the main routing table for this VPC // Get the main routing table for this VPC
filter := ec2.NewFilter() // Really Ugly need to make this better - rmenn
filter.Add("association.main", "true") filter1 := &ec2.Filter{
filter.Add("vpc-id", d.Id()) Name: aws.String("association.main"),
routeResp, err := ec2conn.DescribeRouteTables(nil, filter) Values: []string{("true")},
}
filter2 := &ec2.Filter{
Name: aws.String("vpc-id"),
Values: []string{(d.Id())},
}
DescribeRouteOpts := &ec2.DescribeRouteTablesRequest{
Filters: []ec2.Filter{*filter1, *filter2},
}
routeResp, err := ec2conn.DescribeRouteTables(DescribeRouteOpts)
if err != nil { if err != nil {
return err return err
} }
if v := routeResp.RouteTables; len(v) > 0 { if v := routeResp.RouteTables; len(v) > 0 {
d.Set("main_route_table_id", v[0].RouteTableId) d.Set("main_route_table_id", *v[0].RouteTableID)
} }
resourceAwsVpcSetDefaultNetworkAcl(ec2conn, d) resourceAwsVpcSetDefaultNetworkAcl(ec2conn, d)
@ -157,20 +180,24 @@ func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error {
} }
func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error { func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error {
ec2conn := meta.(*AWSClient).ec2conn ec2conn := meta.(*AWSClient).awsEC2conn
// Turn on partial mode // Turn on partial mode
d.Partial(true) d.Partial(true)
vpcid := d.Id()
modifyOpts := &ec2.ModifyVPCAttributeRequest{
VPCID: &vpcid,
}
if d.HasChange("enable_dns_hostnames") { if d.HasChange("enable_dns_hostnames") {
options := new(ec2.ModifyVpcAttribute) val := d.Get("enable_dns_hostnames").(bool)
options.EnableDnsHostnames = d.Get("enable_dns_hostnames").(bool) modifyOpts.EnableDNSHostnames = &ec2.AttributeBooleanValue{
options.SetEnableDnsHostnames = true Value: &val,
}
log.Printf( log.Printf(
"[INFO] Modifying enable_dns_hostnames vpc attribute for %s: %#v", "[INFO] Modifying enable_dns_hostnames vpc attribute for %s: %#v",
d.Id(), options) d.Id(), modifyOpts)
if _, err := ec2conn.ModifyVpcAttribute(d.Id(), options); err != nil { if err := ec2conn.ModifyVPCAttribute(modifyOpts); err != nil {
return err return err
} }
@ -178,21 +205,22 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error {
} }
if d.HasChange("enable_dns_support") { if d.HasChange("enable_dns_support") {
options := new(ec2.ModifyVpcAttribute) val := d.Get("enable_dns_hostnames").(bool)
options.EnableDnsSupport = d.Get("enable_dns_support").(bool) modifyOpts.EnableDNSSupport = &ec2.AttributeBooleanValue{
options.SetEnableDnsSupport = true Value: &val,
}
log.Printf( log.Printf(
"[INFO] Modifying enable_dns_support vpc attribute for %s: %#v", "[INFO] Modifying enable_dns_support vpc attribute for %s: %#v",
d.Id(), options) d.Id(), modifyOpts)
if _, err := ec2conn.ModifyVpcAttribute(d.Id(), options); err != nil { if err := ec2conn.ModifyVPCAttribute(modifyOpts); err != nil {
return err return err
} }
d.SetPartial("enable_dns_support") d.SetPartial("enable_dns_support")
} }
if err := setTags(ec2conn, d); err != nil { if err := setTagsSDK(ec2conn, d); err != nil {
return err return err
} else { } else {
d.SetPartial("tags") d.SetPartial("tags")
@ -203,11 +231,14 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error {
} }
func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error { func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error {
ec2conn := meta.(*AWSClient).ec2conn ec2conn := meta.(*AWSClient).awsEC2conn
vpcID := d.Id()
DeleteVpcOpts := &ec2.DeleteVPCRequest{
VPCID: &vpcID,
}
log.Printf("[INFO] Deleting VPC: %s", d.Id()) log.Printf("[INFO] Deleting VPC: %s", d.Id())
if _, err := ec2conn.DeleteVpc(d.Id()); err != nil { if err := ec2conn.DeleteVPC(DeleteVpcOpts); err != nil {
ec2err, ok := err.(*ec2.Error) ec2err, ok := err.(*aws.APIError)
if ok && ec2err.Code == "InvalidVpcID.NotFound" { if ok && ec2err.Code == "InvalidVpcID.NotFound" {
return nil return nil
} }
@ -222,9 +253,12 @@ func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error {
// a VPC. // a VPC.
func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) { return func() (interface{}, string, error) {
resp, err := conn.DescribeVpcs([]string{id}, ec2.NewFilter()) DescribeVpcOpts := &ec2.DescribeVPCsRequest{
VPCIDs: []string{id},
}
resp, err := conn.DescribeVPCs(DescribeVpcOpts)
if err != nil { if err != nil {
if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidVpcID.NotFound" { if ec2err, ok := err.(*aws.APIError); ok && ec2err.Code == "InvalidVpcID.NotFound" {
resp = nil resp = nil
} else { } else {
log.Printf("Error on VPCStateRefresh: %s", err) log.Printf("Error on VPCStateRefresh: %s", err)
@ -239,37 +273,53 @@ func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc {
} }
vpc := &resp.VPCs[0] vpc := &resp.VPCs[0]
return vpc, vpc.State, nil return vpc, *vpc.State, nil
} }
} }
func resourceAwsVpcSetDefaultNetworkAcl(conn *ec2.EC2, d *schema.ResourceData) error { func resourceAwsVpcSetDefaultNetworkAcl(conn *ec2.EC2, d *schema.ResourceData) error {
filter := ec2.NewFilter() filter1 := &ec2.Filter{
filter.Add("default", "true") Name: aws.String("default"),
filter.Add("vpc-id", d.Id()) Values: []string{("true")},
networkAclResp, err := conn.NetworkAcls(nil, filter) }
filter2 := &ec2.Filter{
Name: aws.String("vpc-id"),
Values: []string{(d.Id())},
}
DescribeNetworkACLOpts := &ec2.DescribeNetworkACLsRequest{
Filters: []ec2.Filter{*filter1, *filter2},
}
networkAclResp, err := conn.DescribeNetworkACLs(DescribeNetworkACLOpts)
if err != nil { if err != nil {
return err return err
} }
if v := networkAclResp.NetworkAcls; len(v) > 0 { if v := networkAclResp.NetworkACLs; len(v) > 0 {
d.Set("default_network_acl_id", v[0].NetworkAclId) d.Set("default_network_acl_id", v[0].NetworkACLID)
} }
return nil return nil
} }
func resourceAwsVpcSetDefaultSecurityGroup(conn *ec2.EC2, d *schema.ResourceData) error { func resourceAwsVpcSetDefaultSecurityGroup(conn *ec2.EC2, d *schema.ResourceData) error {
filter := ec2.NewFilter() filter1 := &ec2.Filter{
filter.Add("group-name", "default") Name: aws.String("group-name"),
filter.Add("vpc-id", d.Id()) Values: []string{("default")},
securityGroupResp, err := conn.SecurityGroups(nil, filter) }
filter2 := &ec2.Filter{
Name: aws.String("vpc-id"),
Values: []string{(d.Id())},
}
DescribeSgOpts := &ec2.DescribeSecurityGroupsRequest{
Filters: []ec2.Filter{*filter1, *filter2},
}
securityGroupResp, err := conn.DescribeSecurityGroups(DescribeSgOpts)
if err != nil { if err != nil {
return err return err
} }
if v := securityGroupResp.Groups; len(v) > 0 { if v := securityGroupResp.SecurityGroups; len(v) > 0 {
d.Set("default_security_group_id", v[0].Id) d.Set("default_security_group_id", v[0].GroupID)
} }
return nil return nil

View File

@ -2,11 +2,11 @@ package aws
import ( import (
"fmt" "fmt"
"testing" "github.com/hashicorp/aws-sdk-go/aws"
"github.com/hashicorp/aws-sdk-go/gen/ec2"
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/goamz/ec2" "testing"
) )
func TestAccVpc_basic(t *testing.T) { func TestAccVpc_basic(t *testing.T) {
@ -65,7 +65,7 @@ func TestAccVpc_tags(t *testing.T) {
testAccCheckVpcCidr(&vpc, "10.1.0.0/16"), testAccCheckVpcCidr(&vpc, "10.1.0.0/16"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"aws_vpc.foo", "cidr_block", "10.1.0.0/16"), "aws_vpc.foo", "cidr_block", "10.1.0.0/16"),
testAccCheckTags(&vpc.Tags, "foo", "bar"), testAccCheckTagsSDK(&vpc.Tags, "foo", "bar"),
), ),
}, },
@ -73,8 +73,8 @@ func TestAccVpc_tags(t *testing.T) {
Config: testAccVpcConfigTagsUpdate, Config: testAccVpcConfigTagsUpdate,
Check: resource.ComposeTestCheckFunc( Check: resource.ComposeTestCheckFunc(
testAccCheckVpcExists("aws_vpc.foo", &vpc), testAccCheckVpcExists("aws_vpc.foo", &vpc),
testAccCheckTags(&vpc.Tags, "foo", ""), testAccCheckTagsSDK(&vpc.Tags, "foo", ""),
testAccCheckTags(&vpc.Tags, "bar", "baz"), testAccCheckTagsSDK(&vpc.Tags, "bar", "baz"),
), ),
}, },
}, },
@ -111,7 +111,7 @@ func TestAccVpcUpdate(t *testing.T) {
} }
func testAccCheckVpcDestroy(s *terraform.State) error { func testAccCheckVpcDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn conn := testAccProvider.Meta().(*AWSClient).awsEC2conn
for _, rs := range s.RootModule().Resources { for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_vpc" { if rs.Type != "aws_vpc" {
@ -119,7 +119,10 @@ func testAccCheckVpcDestroy(s *terraform.State) error {
} }
// Try to find the VPC // Try to find the VPC
resp, err := conn.DescribeVpcs([]string{rs.Primary.ID}, ec2.NewFilter()) DescribeVpcOpts := &ec2.DescribeVPCsRequest{
VPCIDs: []string{rs.Primary.ID},
}
resp, err := conn.DescribeVPCs(DescribeVpcOpts)
if err == nil { if err == nil {
if len(resp.VPCs) > 0 { if len(resp.VPCs) > 0 {
return fmt.Errorf("VPCs still exist.") return fmt.Errorf("VPCs still exist.")
@ -129,7 +132,7 @@ func testAccCheckVpcDestroy(s *terraform.State) error {
} }
// Verify the error is what we want // Verify the error is what we want
ec2err, ok := err.(*ec2.Error) ec2err, ok := err.(*aws.APIError)
if !ok { if !ok {
return err return err
} }
@ -143,8 +146,9 @@ func testAccCheckVpcDestroy(s *terraform.State) error {
func testAccCheckVpcCidr(vpc *ec2.VPC, expected string) resource.TestCheckFunc { func testAccCheckVpcCidr(vpc *ec2.VPC, expected string) resource.TestCheckFunc {
return func(s *terraform.State) error { return func(s *terraform.State) error {
if vpc.CidrBlock != expected { CIDRBlock := vpc.CIDRBlock
return fmt.Errorf("Bad cidr: %s", vpc.CidrBlock) if *CIDRBlock != expected {
return fmt.Errorf("Bad cidr: %s", *vpc.CIDRBlock)
} }
return nil return nil
@ -162,8 +166,11 @@ func testAccCheckVpcExists(n string, vpc *ec2.VPC) resource.TestCheckFunc {
return fmt.Errorf("No VPC ID is set") return fmt.Errorf("No VPC ID is set")
} }
conn := testAccProvider.Meta().(*AWSClient).ec2conn conn := testAccProvider.Meta().(*AWSClient).awsEC2conn
resp, err := conn.DescribeVpcs([]string{rs.Primary.ID}, ec2.NewFilter()) DescribeVpcOpts := &ec2.DescribeVPCsRequest{
VPCIDs: []string{rs.Primary.ID},
}
resp, err := conn.DescribeVPCs(DescribeVpcOpts)
if err != nil { if err != nil {
return err return err
} }