Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Add initial support for Elastic Network Interfaces.
Browse files Browse the repository at this point in the history
Add methods to list, create, delete, attach, and detach ENI's.  Also
fixed a bug in run_instances related to security group ID's.
Closes #454 #455.

Requested-by: Mitch Garnaat <mitch@garnaat.com>
Signed-off-by: Mitch Garnaat <mitch@garnaat.com>
  • Loading branch information
garnaat committed Jan 2, 2012
1 parent 2892b6a commit 9c823ff
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 3 deletions.
123 changes: 120 additions & 3 deletions boto/ec2/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@
from boto.ec2.placementgroup import PlacementGroup
from boto.ec2.tag import Tag
from boto.ec2.instancestatus import InstanceStatusSet
from boto.ec2.networkinterface import NetworkInterface
from boto.exception import EC2ResponseError

#boto.set_stream_logger('ec2')

class EC2Connection(AWSQueryConnection):

APIVersion = boto.config.get('Boto', 'ec2_version', '2011-11-01')
APIVersion = boto.config.get('Boto', 'ec2_version', '2011-12-15')
DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
'ec2.amazonaws.com')
Expand Down Expand Up @@ -625,7 +626,7 @@ def run_instances(self, image_id, min_count=1, max_count=1,
l = []
for group in security_group_ids:
if isinstance(group, SecurityGroup):
l.append(group.name)
l.append(group.id)
else:
l.append(group)
self.build_list_params(params, l, 'SecurityGroupId')
Expand Down Expand Up @@ -1821,7 +1822,8 @@ def import_key_pair(self, key_name, public_key_material):

# SecurityGroup methods

def get_all_security_groups(self, groupnames=None, group_ids=None, filters=None):
def get_all_security_groups(self, groupnames=None, group_ids=None,
filters=None):
"""
Get all security groups associated with your account in a region.
Expand Down Expand Up @@ -2725,3 +2727,118 @@ def delete_tags(self, resource_ids, tags):
self.build_tag_param_list(params, tags)
return self.get_status('DeleteTags', params, verb='POST')

# Network Interface methods

def get_all_network_interfaces(self, filters=None):
"""
Retrieve all of the Elastic Network Interfaces (ENI's)
associated with your account.
:type filters: dict
:param filters: Optional filters that can be used to limit
the results returned. Filters are provided
in the form of a dictionary consisting of
filter names as the key and filter values
as the value. The set of allowable filter
names/values is dependent on the request
being performed. Check the EC2 API guide
for details.
:rtype: list
:return: A list of :class:`boto.ec2.networkinterface.NetworkInterface`
"""
params = {}
if filters:
self.build_filter_params(params, filters)
return self.get_list('DescribeNetworkInterfaces', params,
[('item', NetworkInterface)], verb='POST')

def create_network_interface(self, subnet_id, private_ip_address=None,
description=None, groups=None):
"""
Creates a network interface in the specified subnet.
:type subnet_id: str
:param subnet_id: The ID of the subnet to associate with the
network interface.
:type private_ip_address: str
:param private_ip_address: The private IP address of the
network interface. If not supplied, one will be chosen
for you.
:type description: str
:param description: The description of the network interface.
:type groups: list
:param groups: Lists the groups for use by the network interface.
This can be either a list of group ID's or a list of
:class:`boto.ec2.securitygroup.SecurityGroup` objects.
:rtype: :class:`boto.ec2.networkinterface.NetworkInterface`
:return: The newly created network interface.
"""
params = {'SubnetId' : subnet_id}
if private_ip_address:
params['PrivateIpAddress'] = private_ip_address
if description:
params['Description'] = description
if groups:
ids = []
for group in groups:
if isinstance(group, SecurityGroup):
ids.append(group.id)
else:
ids.append(group)
self.build_list_params(params, ids, 'SecurityGroupId')
return self.get_object('CreateNetworkInterface', params,
NetworkInterface, verb='POST')

def attach_network_interface(self, network_interface_id,
instance_id, device_index):
"""
Attaches a network interface to an instance.
:type network_interface_id: str
:param network_interface_id: The ID of the network interface to attach.
:type instance_id: str
:param instance_id: The ID of the instance that will be attached
to the network interface.
:type device_index: int
:param device_index: The index of the device for the network
interface attachment on the instance.
"""
params = {'NetworkInterfaceId' : network_interface_id,
'InstanceId' : instance_id,
'Deviceindex' : device_index}
return self.get_status('AttachNetworkInterface', params, verb='POST')

def detach_network_interface(self, network_interface_id, force=False):
"""
Detaches a network interface from an instance.
:type network_interface_id: str
:param network_interface_id: The ID of the network interface to detach.
:type force: bool
:param force: Set to true to force a detachment.
"""
params = {'NetworkInterfaceId' : network_interface_id}
if force:
params['Force'] = 'true'
return self.get_status('DetachNetworkInterface', params, verb='POST')

def delete_network_interface(self, network_interface_id):
"""
Delete the specified network interface.
:type network_interface_id: str
:param network_interface_id: The ID of the network interface to delete.
"""
params = {'NetworkInterfaceId' : network_interface_id}
return self.get_status('DeleteNetworkInterface', params, verb='POST')

133 changes: 133 additions & 0 deletions boto/ec2/networkinterface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Copyright (c) 2011 Mitch Garnaat http://garnaat.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

"""
Represents an EC2 Elastic Network Interface
"""
from boto.ec2.ec2object import TaggedEC2Object
from boto.resultset import ResultSet
from boto.ec2.instance import Group

class Attachment(object):

def __init__(self):
self.id = None
self.instance_id = None
self.instance_owner_id = None
self.device_index = 0
self.status = None
self.attach_time = None
self.delete_on_termination = False

def __repr__(self):
return 'Attachment:%s' % self.id

def startElement(self, name, attrs, connection):
return None

def endElement(self, name, value, connection):
if name == 'attachmentId':
self.id = value
elif name == 'instanceId':
self.instance_id = value
elif name == 'instanceOwnerId':
self.instance_owner_id = value
elif name == 'status':
self.status = value
elif name == 'attachTime':
self.attach_time = value
elif name == 'deleteOnTermination':
if value.lower() == 'true':
self.delete_on_termination = True
else:
self.delete_on_termination = False
else:
setattr(self, name, value)

class NetworkInterface(TaggedEC2Object):

def __init__(self, connection=None):
TaggedEC2Object.__init__(self, connection)
self.id = None
self.subnet_id = None
self.vpc_id = None
self.availability_zone = None
self.description = None
self.owner_id = None
self.requester_managed = False
self.status = None
self.mac_address = None
self.private_ip_address = None
self.source_dest_check = None
self.groups = []
self.attachment = None

def __repr__(self):
return 'NetworkInterface:%s' % self.id

def startElement(self, name, attrs, connection):
if name == 'groupSet':
self.groups = ResultSet([('item', Group)])
return self.groups
elif name == 'attachment':
self.attachment = Attachment()
return self.attachment
else:
return None

def endElement(self, name, value, connection):
if name == 'networkInterfaceId':
self.id = value
elif name == 'subnetId':
self.subnet_id = value
elif name == 'vpcId':
self.vpc_id = value
elif name == 'availabilityZone':
self.availability_zone = value
elif name == 'description':
self.description = value
elif name == 'ownerId':
self.owner_id = value
elif name == 'requesterManaged':
if value.lower() == 'true':
self.requester_managed = True
else:
self.requester_managed = False
elif name == 'status':
self.status = value
elif name == 'macAddress':
self.mac_address = value
elif name == 'privateIpAddress':
self.private_ip_address = value
elif name == 'sourceDestCheck':
if value.lower() == 'true':
self.source_dest_check = True
else:
self.source_dest_check = False
else:
setattr(self, name, value)

def delete(self):
return self.connection.delete_network_interface(self.id)




0 comments on commit 9c823ff

Please sign in to comment.