ec2: use filters for GetSubnets; check subnetId in PreCreate for driver

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2015-02-27 16:51:48 -05:00
parent 19f5b0cb54
commit 32ed441fbb
No known key found for this signature in database
GPG Key ID: A519480096146526
4 changed files with 67 additions and 25 deletions

View File

@ -210,6 +210,42 @@ func (d *Driver) checkPrereqs() error {
if key != nil { 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) 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 return nil
} }
@ -240,28 +276,8 @@ func (d *Driver) Create() error {
} }
// get the subnet id // get the subnet id
regionZone := d.Region + d.Zone
subnetId := d.SubnetId subnetId := d.SubnetId
if d.SubnetId == "" {
subnets, err := d.getClient().GetSubnets()
if err != nil {
return err
}
for _, s := range subnets {
if s.AvailabilityZone == regionZone && s.VpcId == d.VpcId {
subnetId = s.SubnetId
break
}
}
}
if subnetId == "" {
return fmt.Errorf("unable to find a subnet in the zone: %s", regionZone)
}
log.Debugf("launching instance in subnet %s", subnetId) 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) instance, err := d.getClient().RunInstance(d.AMI, d.InstanceType, d.Zone, 1, 1, d.SecurityGroupId, d.KeyName, subnetId, bdm)
@ -270,7 +286,19 @@ func (d *Driver) Create() error {
} }
d.InstanceId = instance.InstanceId 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 != "" {
d.IPAddress = instance.IpAddress d.IPAddress = instance.IpAddress
break
}
time.Sleep(5 * time.Second)
}
if len(instance.NetworkInterfaceSet) > 0 { if len(instance.NetworkInterfaceSet) > 0 {
d.PrivateIPAddress = instance.NetworkInterfaceSet[0].PrivateIpAddress d.PrivateIPAddress = instance.NetworkInterfaceSet[0].PrivateIpAddress

View File

@ -11,4 +11,5 @@ type Subnet struct {
VpcId string `xml:"vpcId"` VpcId string `xml:"vpcId"`
CidrBlock string `xml:"cidrBlock"` CidrBlock string `xml:"cidrBlock"`
AvailabilityZone string `xml:"availabilityZone"` AvailabilityZone string `xml:"availabilityZone"`
DefaultForAz bool `xml:"defaultForAz"`
} }

View File

@ -417,13 +417,20 @@ func (e *EC2) GetSecurityGroupById(id string) (*SecurityGroup, error) {
return nil, nil return nil, nil
} }
func (e *EC2) GetSubnets() ([]Subnet, error) { func (e *EC2) GetSubnets(filters []Filter) ([]Subnet, error) {
subnets := []Subnet{} subnets := []Subnet{}
resp, err := e.performStandardAction("DescribeSubnets") v := url.Values{}
if err != nil { v.Set("Action", "DescribeSubnets")
return subnets, err
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() defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body) contents, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return subnets, fmt.Errorf("Error reading AWS response body: %s", err) return subnets, fmt.Errorf("Error reading AWS response body: %s", err)

View File

@ -0,0 +1,6 @@
package amz
type Filter struct {
Name string
Value string
}