Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

ec2: check subnet exists in vpc #664

Merged
merged 3 commits into from Mar 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 50 additions & 26 deletions drivers/amazonec2/amazonec2.go
Expand Up @@ -210,6 +210,42 @@ func (d *Driver) checkPrereqs() error {
if key != nil {
return fmt.Errorf("There is already a keypair with the name %s. Please either remove that keypair or use a different machine name.", d.MachineName)
}

regionZone := d.Region + d.Zone
if d.SubnetId == "" {
filters := []amz.Filter{
{
Name: "availabilityZone",
Value: regionZone,
},
{
Name: "vpc-id",
Value: d.VpcId,
},
}

subnets, err := d.getClient().GetSubnets(filters)
if err != nil {
return err
}

if len(subnets) == 0 {
return fmt.Errorf("unable to find a subnet in the zone: %s", regionZone)
}

d.SubnetId = subnets[0].SubnetId

// try to find default
if len(subnets) > 1 {
for _, subnet := range subnets {
if subnet.DefaultForAz {
d.SubnetId = subnet.SubnetId
break
}
}
}
}

return nil
}

Expand Down Expand Up @@ -239,39 +275,28 @@ func (d *Driver) Create() error {
VolumeType: "gp2",
}

// get the subnet id
regionZone := d.Region + d.Zone
subnetId := d.SubnetId
log.Debugf("launching instance in subnet %s", d.SubnetId)
instance, err := d.getClient().RunInstance(d.AMI, d.InstanceType, d.Zone, 1, 1, d.SecurityGroupId, d.KeyName, d.SubnetId, bdm)

if d.SubnetId == "" {
subnets, err := d.getClient().GetSubnets()
if err != nil {
return fmt.Errorf("Error launching instance: %s", err)
}

d.InstanceId = instance.InstanceId
log.Debug("waiting for ip address to become available")
for {
ip, err := d.GetIP()
if err != nil {
return err
}
if ip != "" {

for _, s := range subnets {
if s.AvailabilityZone == regionZone {
subnetId = s.SubnetId
break
}
d.IPAddress = instance.IpAddress
break
}

time.Sleep(5 * time.Second)
}

if subnetId == "" {
return fmt.Errorf("unable to find a subnet in the zone: %s", regionZone)
}

log.Debugf("launching instance in subnet %s", subnetId)
instance, err := d.getClient().RunInstance(d.AMI, d.InstanceType, d.Zone, 1, 1, d.SecurityGroupId, d.KeyName, subnetId, bdm)

if err != nil {
return fmt.Errorf("Error launching instance: %s", err)
}

d.InstanceId = instance.InstanceId
d.IPAddress = instance.IpAddress

if len(instance.NetworkInterfaceSet) > 0 {
d.PrivateIPAddress = instance.NetworkInterfaceSet[0].PrivateIpAddress
}
Expand Down Expand Up @@ -320,7 +345,6 @@ func (d *Driver) Create() error {
}

func (d *Driver) GetURL() (string, error) {

if d.IPAddress == "" {
return "", nil
}
Expand Down
1 change: 1 addition & 0 deletions drivers/amazonec2/amz/describe_subnets.go
Expand Up @@ -11,4 +11,5 @@ type Subnet struct {
VpcId string `xml:"vpcId"`
CidrBlock string `xml:"cidrBlock"`
AvailabilityZone string `xml:"availabilityZone"`
DefaultForAz bool `xml:"defaultForAz"`
}
15 changes: 11 additions & 4 deletions drivers/amazonec2/amz/ec2.go
Expand Up @@ -417,13 +417,20 @@ func (e *EC2) GetSecurityGroupById(id string) (*SecurityGroup, error) {
return nil, nil
}

func (e *EC2) GetSubnets() ([]Subnet, error) {
func (e *EC2) GetSubnets(filters []Filter) ([]Subnet, error) {
subnets := []Subnet{}
resp, err := e.performStandardAction("DescribeSubnets")
if err != nil {
return subnets, err
v := url.Values{}
v.Set("Action", "DescribeSubnets")

for idx, filter := range filters {
n := idx + 1 // amazon starts counting from 1 not 0
v.Set(fmt.Sprintf("Filter.%d.Name", n), filter.Name)
v.Set(fmt.Sprintf("Filter.%d.Value", n), filter.Value)
}

resp, err := e.awsApiCall(v)
defer resp.Body.Close()

contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
return subnets, fmt.Errorf("Error reading AWS response body: %s", err)
Expand Down
6 changes: 6 additions & 0 deletions drivers/amazonec2/amz/filter.go
@@ -0,0 +1,6 @@
package amz

type Filter struct {
Name string
Value string
}