Updated inventory plugins from ansible, updated all third party packages in awx/lib/site-packages to latest versions, minor serializer fixes after package upgrades.

This commit is contained in:
Chris Church
2014-03-31 13:25:43 -04:00
parent 9e898953dd
commit 56f8d6748b
973 changed files with 58591 additions and 20608 deletions

View File

@@ -24,21 +24,10 @@ This module provides an interface to the Elastic Compute Cloud (EC2)
service from AWS.
"""
from boto.ec2.connection import EC2Connection
from boto.regioninfo import RegionInfo
from boto.regioninfo import RegionInfo, get_regions, load_regions
RegionData = {
'us-east-1': 'ec2.us-east-1.amazonaws.com',
'us-gov-west-1': 'ec2.us-gov-west-1.amazonaws.com',
'us-west-1': 'ec2.us-west-1.amazonaws.com',
'us-west-2': 'ec2.us-west-2.amazonaws.com',
'sa-east-1': 'ec2.sa-east-1.amazonaws.com',
'eu-west-1': 'ec2.eu-west-1.amazonaws.com',
'ap-northeast-1': 'ec2.ap-northeast-1.amazonaws.com',
'ap-southeast-1': 'ec2.ap-southeast-1.amazonaws.com',
'ap-southeast-2': 'ec2.ap-southeast-2.amazonaws.com',
'cn-north-1': 'ec2.cn-north-1.amazonaws.com.cn',
}
RegionData = load_regions().get('ec2', {})
def regions(**kw_params):
@@ -51,13 +40,7 @@ def regions(**kw_params):
:rtype: list
:return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
"""
regions = []
for region_name in RegionData:
region = RegionInfo(name=region_name,
endpoint=RegionData[region_name],
connection_cls=EC2Connection)
regions.append(region)
return regions
return get_regions('ec2', connection_cls=EC2Connection)
def connect_to_region(region_name, **kw_params):

View File

@@ -89,14 +89,23 @@ class Address(EC2Object):
delete = release
def associate(self, instance_id, dry_run=False):
def associate(self, instance_id, allow_reassociation=False, dry_run=False):
"""
Associate this Elastic IP address with a currently running instance.
:see: :meth:`boto.ec2.connection.EC2Connection.associate_address`
"""
if self.allocation_id:
return self.connection.associate_address(
instance_id,
self.public_ip,
allocation_id=self.allocation_id,
allow_reassociation=allow_reassociation,
dry_run=dry_run
)
return self.connection.associate_address(
instance_id,
self.public_ip,
allow_reassociation=allow_reassociation,
dry_run=dry_run
)

View File

@@ -31,7 +31,7 @@ import base64
import boto
from boto.connection import AWSQueryConnection
from boto.ec2.regioninfo import RegionInfo
from boto.regioninfo import RegionInfo, get_regions, load_regions
from boto.ec2.autoscale.request import Request
from boto.ec2.autoscale.launchconfig import LaunchConfiguration
from boto.ec2.autoscale.group import AutoScalingGroup
@@ -44,19 +44,9 @@ from boto.ec2.autoscale.policy import TerminationPolicies
from boto.ec2.autoscale.instance import Instance
from boto.ec2.autoscale.scheduled import ScheduledUpdateGroupAction
from boto.ec2.autoscale.tag import Tag
from boto.ec2.autoscale.limits import AccountLimits
RegionData = {
'us-east-1': 'autoscaling.us-east-1.amazonaws.com',
'us-gov-west-1': 'autoscaling.us-gov-west-1.amazonaws.com',
'us-west-1': 'autoscaling.us-west-1.amazonaws.com',
'us-west-2': 'autoscaling.us-west-2.amazonaws.com',
'sa-east-1': 'autoscaling.sa-east-1.amazonaws.com',
'eu-west-1': 'autoscaling.eu-west-1.amazonaws.com',
'ap-northeast-1': 'autoscaling.ap-northeast-1.amazonaws.com',
'ap-southeast-1': 'autoscaling.ap-southeast-1.amazonaws.com',
'ap-southeast-2': 'autoscaling.ap-southeast-2.amazonaws.com',
'cn-north-1': 'autoscaling.cn-north-1.amazonaws.com.cn',
}
RegionData = load_regions().get('autoscaling', {})
def regions():
@@ -66,13 +56,7 @@ def regions():
:rtype: list
:return: A list of :class:`boto.RegionInfo` instances
"""
regions = []
for region_name in RegionData:
region = RegionInfo(name=region_name,
endpoint=RegionData[region_name],
connection_cls=AutoScaleConnection)
regions.append(region)
return regions
return get_regions('autoscaling', connection_cls=AutoScaleConnection)
def connect_to_region(region_name, **kw_params):
@@ -103,18 +87,22 @@ class AutoScaleConnection(AWSQueryConnection):
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
security_token=None, validate_certs=True):
security_token=None, validate_certs=True, profile_name=None,
use_block_device_types=False):
"""
Init method to create a new connection to the AutoScaling service.
B{Note:} The host argument is overridden by the host specified in the
boto configuration file.
"""
if not region:
region = RegionInfo(self, self.DefaultRegionName,
self.DefaultRegionEndpoint,
AutoScaleConnection)
self.region = region
self.use_block_device_types = use_block_device_types
super(AutoScaleConnection, self).__init__(aws_access_key_id,
aws_secret_access_key,
is_secure, port, proxy, proxy_port,
@@ -122,7 +110,8 @@ class AutoScaleConnection(AWSQueryConnection):
self.region.endpoint, debug,
https_connection_factory, path=path,
security_token=security_token,
validate_certs=validate_certs)
validate_certs=validate_certs,
profile_name=profile_name)
def _required_auth_capability(self):
return ['hmac-v4']
@@ -176,6 +165,8 @@ class AutoScaleConnection(AWSQueryConnection):
params['DefaultCooldown'] = as_group.default_cooldown
if as_group.placement_group:
params['PlacementGroup'] = as_group.placement_group
if as_group.instance_id:
params['InstanceId'] = as_group.instance_id
if as_group.termination_policies:
self.build_list_params(params, as_group.termination_policies,
'TerminationPolicies')
@@ -190,6 +181,16 @@ class AutoScaleConnection(AWSQueryConnection):
tag.build_params(params, i + 1)
return self.get_object(op, params, Request)
def attach_instances(self, name, instance_ids):
"""
Attach instances to an autoscaling group.
"""
params = {
'AutoScalingGroupName': name,
}
self.build_list_params(params, instance_ids, 'InstanceIds')
return self.get_status('AttachInstances', params)
def create_auto_scaling_group(self, as_group):
"""
Create auto scaling group.
@@ -246,9 +247,25 @@ class AutoScaleConnection(AWSQueryConnection):
params['AssociatePublicIpAddress'] = 'true'
elif launch_config.associate_public_ip_address is False:
params['AssociatePublicIpAddress'] = 'false'
if launch_config.volume_type:
params['VolumeType'] = launch_config.volume_type
if launch_config.delete_on_termination:
params['DeleteOnTermination'] = 'true'
else:
params['DeleteOnTermination'] = 'false'
if launch_config.iops:
params['Iops'] = launch_config.iops
return self.get_object('CreateLaunchConfiguration', params,
Request, verb='POST')
def get_account_limits(self):
"""
Returns the limits for the Auto Scaling resources currently granted for
your AWS account.
"""
params = {}
return self.get_object('DescribeAccountLimits', params, AccountLimits)
def create_scaling_policy(self, scaling_policy):
"""
Creates a new Scaling Policy.

View File

@@ -98,7 +98,8 @@ class AutoScalingGroup(object):
health_check_type=None, health_check_period=None,
placement_group=None, vpc_zone_identifier=None,
desired_capacity=None, min_size=None, max_size=None,
tags=None, termination_policies=None, **kwargs):
tags=None, termination_policies=None, instance_id=None,
**kwargs):
"""
Creates a new AutoScalingGroup with the specified name.
@@ -145,12 +146,12 @@ class AutoScalingGroup(object):
:param placement_group: Physical location of your cluster placement
group created in Amazon EC2.
:type vpc_zone_identifier: str
:param vpc_zone_identifier: The subnet identifier of the Virtual
Private Cloud.
:type vpc_zone_identifier: str or list
:param vpc_zone_identifier: A comma-separated string or python list of
the subnet identifiers of the Virtual Private Cloud.
:type tags: list
:param tags: List of :class:`boto.ec2.autoscale.tag.Tag`s
:param tags: List of :class:`boto.ec2.autoscale.tag.Tag`s
:type termination_policies: list
:param termination_policies: A list of termination policies. Valid values
@@ -158,6 +159,10 @@ class AutoScalingGroup(object):
"ClosestToNextInstanceHour", "Default". If no value is specified,
the "Default" value is used.
:type instance_id: str
:param instance_id: The ID of the Amazon EC2 instance you want to use
to create the Auto Scaling group.
:rtype: :class:`boto.ec2.autoscale.group.AutoScalingGroup`
:return: An autoscale group.
"""
@@ -183,11 +188,14 @@ class AutoScalingGroup(object):
self.health_check_type = health_check_type
self.placement_group = placement_group
self.autoscaling_group_arn = None
if type(vpc_zone_identifier) is list:
vpc_zone_identifier = ','.join(vpc_zone_identifier)
self.vpc_zone_identifier = vpc_zone_identifier
self.instances = None
self.tags = tags or None
termination_policies = termination_policies or []
self.termination_policies = ListElement(termination_policies)
self.instance_id = instance_id
# backwards compatible access to 'cooldown' param
def _get_cooldown(self):
@@ -251,6 +259,8 @@ class AutoScalingGroup(object):
self.health_check_type = value
elif name == 'VPCZoneIdentifier':
self.vpc_zone_identifier = value
elif name == 'InstanceId':
self.instance_id = value
else:
setattr(self, name, value)
@@ -304,7 +314,7 @@ class AutoScalingGroup(object):
'autoscaling:EC2_INSTANCE_LAUNCH_ERROR',
'autoscaling:EC2_INSTANCE_TERMINATE',
'autoscaling:EC2_INSTANCE_TERMINATE_ERROR',
'autoscaling:TEST_NOTIFICATION'
'autoscaling:TEST_NOTIFICATION'
"""
return self.connection.put_notification_configuration(self,
topic,

View File

@@ -21,14 +21,16 @@
# IN THE SOFTWARE.
from datetime import datetime
from boto.resultset import ResultSet
from boto.ec2.elb.listelement import ListElement
# Namespacing issue with deprecated local class
from boto.ec2.blockdevicemapping import BlockDeviceMapping as BDM
from boto.resultset import ResultSet
import boto.utils
import base64
# this should use the corresponding object from boto.ec2
# Currently in use by deprecated local BlockDeviceMapping class
class Ebs(object):
def __init__(self, connection=None, snapshot_id=None, volume_size=None):
self.connection = connection
@@ -65,12 +67,16 @@ class InstanceMonitoring(object):
# this should use the BlockDeviceMapping from boto.ec2.blockdevicemapping
# Currently in use by deprecated code for backwards compatability
# Removing this class can also remove the Ebs class in this same file
class BlockDeviceMapping(object):
def __init__(self, connection=None, device_name=None, virtual_name=None):
def __init__(self, connection=None, device_name=None, virtual_name=None,
ebs=None, no_device=None):
self.connection = connection
self.device_name = None
self.virtual_name = None
self.ebs = None
self.device_name = device_name
self.virtual_name = virtual_name
self.ebs = ebs
self.no_device = no_device
def __repr__(self):
return 'BlockDeviceMapping(%s, %s)' % (self.device_name,
@@ -86,6 +92,8 @@ class BlockDeviceMapping(object):
self.device_name = value
elif name == 'VirtualName':
self.virtual_name = value
elif name == 'NoDevice':
self.no_device = bool(value)
class LaunchConfiguration(object):
@@ -95,7 +103,8 @@ class LaunchConfiguration(object):
ramdisk_id=None, block_device_mappings=None,
instance_monitoring=False, spot_price=None,
instance_profile_name=None, ebs_optimized=False,
associate_public_ip_address=None):
associate_public_ip_address=None, volume_type=None,
delete_on_termination=True, iops=None, use_block_device_types=False):
"""
A launch configuration.
@@ -147,8 +156,9 @@ class LaunchConfiguration(object):
:param ebs_optimized: Specifies whether the instance is optimized
for EBS I/O (true) or not (false).
:type associate_public_ip_address: bool
:param associate_public_ip_address: Used for Auto Scaling groups that launch instances into an Amazon Virtual Private Cloud.
:param associate_public_ip_address: Used for Auto Scaling groups that launch instances into an Amazon Virtual Private Cloud.
Specifies whether to assign a public IP address to each instance launched in a Amazon VPC.
"""
self.connection = connection
@@ -170,6 +180,13 @@ class LaunchConfiguration(object):
self.launch_configuration_arn = None
self.ebs_optimized = ebs_optimized
self.associate_public_ip_address = associate_public_ip_address
self.volume_type = volume_type
self.delete_on_termination = delete_on_termination
self.iops = iops
self.use_block_device_types = use_block_device_types
if connection is not None:
self.use_block_device_types = connection.use_block_device_types
def __repr__(self):
return 'LaunchConfiguration:%s' % self.name
@@ -178,8 +195,10 @@ class LaunchConfiguration(object):
if name == 'SecurityGroups':
return self.security_groups
elif name == 'BlockDeviceMappings':
self.block_device_mappings = ResultSet([('member',
BlockDeviceMapping)])
if self.use_block_device_types:
self.block_device_mappings = BDM()
else:
self.block_device_mappings = ResultSet([('member', BlockDeviceMapping)])
return self.block_device_mappings
elif name == 'InstanceMonitoring':
self.instance_monitoring = InstanceMonitoring(self)
@@ -215,6 +234,17 @@ class LaunchConfiguration(object):
self.instance_profile_name = value
elif name == 'EbsOptimized':
self.ebs_optimized = True if value.lower() == 'true' else False
elif name == 'AssociatePublicIpAddress':
self.associate_public_ip_address = True if value.lower() == 'true' else False
elif name == 'VolumeType':
self.volume_type = value
elif name == 'DeleteOnTermination':
if value.lower() == 'true':
self.delete_on_termination = True
else:
self.delete_on_termination = False
elif name == 'Iops':
self.iops = int(value)
else:
setattr(self, name, value)

View File

@@ -0,0 +1,44 @@
# Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved
#
# 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.
class AccountLimits(object):
def __init__(self, connection=None):
self.connection = connection
self.max_autoscaling_groups = None
self.max_launch_configurations = None
def __repr__(self):
return 'AccountLimits: [%s, %s]' % (self.max_autoscaling_groups,
self.max_launch_configurations)
def startElement(self, name, attrs, connection):
return None
def endElement(self, name, value, connection):
if name == 'RequestId':
self.request_id = value
elif name == 'MaxNumberOfAutoScalingGroups':
self.max_autoscaling_groups = int(value)
elif name == 'MaxNumberOfLaunchConfigurations':
self.max_launch_configurations = int(value)
else:
setattr(self, name, value)

View File

@@ -47,16 +47,17 @@ class Alarm(object):
class AdjustmentType(object):
def __init__(self, connection=None):
self.connection = connection
self.adjustment_types = ListElement([])
self.adjustment_type = None
def __repr__(self):
return 'AdjustmentType:%s' % self.adjustment_types
return 'AdjustmentType:%s' % self.adjustment_type
def startElement(self, name, attrs, connection):
if name == 'AdjustmentType':
return self.adjustment_types
return
def endElement(self, name, value, connection):
if name == 'AdjustmentType':
self.adjustment_type = value
return

View File

@@ -55,25 +55,26 @@ class BlockDeviceType(object):
pass
def endElement(self, name, value, connection):
lname = name.lower()
if name == 'volumeId':
self.volume_id = value
elif name == 'virtualName':
elif lname == 'virtualname':
self.ephemeral_name = value
elif name == 'NoDevice':
elif lname == 'nodevice':
self.no_device = (value == 'true')
elif name == 'snapshotId':
elif lname == 'snapshotid':
self.snapshot_id = value
elif name == 'volumeSize':
elif lname == 'volumesize':
self.size = int(value)
elif name == 'status':
elif lname == 'status':
self.status = value
elif name == 'attachTime':
elif lname == 'attachtime':
self.attach_time = value
elif name == 'deleteOnTermination':
elif lname == 'deleteontermination':
self.delete_on_termination = (value == 'true')
elif name == 'volumeType':
elif lname == 'volumetype':
self.volume_type = value
elif name == 'iops':
elif lname == 'iops':
self.iops = int(value)
else:
setattr(self, name, value)
@@ -105,14 +106,16 @@ class BlockDeviceMapping(dict):
self.current_value = None
def startElement(self, name, attrs, connection):
if name == 'ebs' or name == 'virtualName':
lname = name.lower()
if lname in ['ebs', 'virtualname']:
self.current_value = BlockDeviceType(self)
return self.current_value
def endElement(self, name, value, connection):
if name == 'device' or name == 'deviceName':
lname = name.lower()
if lname in ['device', 'devicename']:
self.current_name = value
elif name == 'item':
elif lname in ['item', 'member']:
self[self.current_name] = self.current_value
def ec2_build_list_params(self, params, prefix=''):

View File

@@ -28,21 +28,10 @@ from boto.connection import AWSQueryConnection
from boto.ec2.cloudwatch.metric import Metric
from boto.ec2.cloudwatch.alarm import MetricAlarm, MetricAlarms, AlarmHistoryItem
from boto.ec2.cloudwatch.datapoint import Datapoint
from boto.regioninfo import RegionInfo
from boto.regioninfo import RegionInfo, get_regions, load_regions
import boto
RegionData = {
'us-east-1': 'monitoring.us-east-1.amazonaws.com',
'us-gov-west-1': 'monitoring.us-gov-west-1.amazonaws.com',
'us-west-1': 'monitoring.us-west-1.amazonaws.com',
'us-west-2': 'monitoring.us-west-2.amazonaws.com',
'sa-east-1': 'monitoring.sa-east-1.amazonaws.com',
'eu-west-1': 'monitoring.eu-west-1.amazonaws.com',
'ap-northeast-1': 'monitoring.ap-northeast-1.amazonaws.com',
'ap-southeast-1': 'monitoring.ap-southeast-1.amazonaws.com',
'ap-southeast-2': 'monitoring.ap-southeast-2.amazonaws.com',
'cn-north-1': 'monitoring.cn-north-1.amazonaws.com.cn',
}
RegionData = load_regions().get('cloudwatch', {})
def regions():
@@ -52,13 +41,7 @@ def regions():
:rtype: list
:return: A list of :class:`boto.RegionInfo` instances
"""
regions = []
for region_name in RegionData:
region = RegionInfo(name=region_name,
endpoint=RegionData[region_name],
connection_cls=CloudWatchConnection)
regions.append(region)
return regions
return get_regions('cloudwatch', connection_cls=CloudWatchConnection)
def connect_to_region(region_name, **kw_params):
@@ -91,7 +74,7 @@ class CloudWatchConnection(AWSQueryConnection):
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
security_token=None, validate_certs=True):
security_token=None, validate_certs=True, profile_name=None):
"""
Init method to create a new connection to EC2 Monitoring Service.
@@ -115,7 +98,8 @@ class CloudWatchConnection(AWSQueryConnection):
self.region.endpoint, debug,
https_connection_factory, path,
security_token,
validate_certs=validate_certs)
validate_certs=validate_certs,
profile_name=profile_name)
def _required_auth_capability(self):
return ['hmac-v4']
@@ -178,11 +162,11 @@ class CloudWatchConnection(AWSQueryConnection):
metric_data['StatisticValues.Minimum'] = s['minimum']
metric_data['StatisticValues.SampleCount'] = s['samplecount']
metric_data['StatisticValues.Sum'] = s['sum']
if value != None:
if value is not None:
msg = 'You supplied a value and statistics for a ' + \
'metric.Posting statistics and not value.'
boto.log.warn(msg)
elif value != None:
elif value is not None:
metric_data['Value'] = v
else:
raise Exception('Must specify a value or statistics to put.')
@@ -273,9 +257,13 @@ class CloudWatchConnection(AWSQueryConnection):
pairs that will be used to filter the results. The key in
the dictionary is the name of a Dimension. The value in
the dictionary is either a scalar value of that Dimension
name that you want to filter on, a list of values to
filter on or None if you want all metrics with that
Dimension name.
name that you want to filter on or None if you want all
metrics with that Dimension name. To be included in the
result a metric must contain all specified dimensions,
although the metric may contain additional dimensions beyond
the requested metrics. The Dimension names, and values must
be strings between 1 and 250 characters long. A maximum of
10 dimensions are allowed.
:type metric_name: str
:param metric_name: The name of the Metric to filter against. If None,

View File

@@ -58,7 +58,7 @@ from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
from boto.ec2.bundleinstance import BundleInstanceTask
from boto.ec2.placementgroup import PlacementGroup
from boto.ec2.tag import Tag
from boto.ec2.vmtype import VmType
from boto.ec2.instancetype import InstanceType
from boto.ec2.instancestatus import InstanceStatusSet
from boto.ec2.volumestatus import VolumeStatusSet
from boto.ec2.networkinterface import NetworkInterface
@@ -83,7 +83,7 @@ class EC2Connection(AWSQueryConnection):
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
api_version=None, security_token=None,
validate_certs=True):
validate_certs=True, profile_name=None):
"""
Init method to create a new connection to EC2.
"""
@@ -98,7 +98,8 @@ class EC2Connection(AWSQueryConnection):
self.region.endpoint, debug,
https_connection_factory, path,
security_token,
validate_certs=validate_certs)
validate_certs=validate_certs,
profile_name=profile_name)
if api_version:
self.APIVersion = api_version
@@ -734,8 +735,8 @@ class EC2Connection(AWSQueryConnection):
launch instances.
:type security_groups: list of strings
:param security_groups: The names of the security groups with which to
associate instances.
:param security_groups: The names of the EC2 classic security groups
with which to associate instances
:type user_data: string
:param user_data: The Base64-encoded MIME user data to be made
@@ -749,6 +750,8 @@ class EC2Connection(AWSQueryConnection):
* m1.medium
* m1.large
* m1.xlarge
* m3.medium
* m3.large
* m3.xlarge
* m3.2xlarge
* c1.medium
@@ -1301,7 +1304,8 @@ class EC2Connection(AWSQueryConnection):
def get_spot_price_history(self, start_time=None, end_time=None,
instance_type=None, product_description=None,
availability_zone=None, dry_run=False,
max_results=None):
max_results=None, next_token=None,
filters=None):
"""
Retrieve the recent history of spot instances pricing.
@@ -1339,6 +1343,19 @@ class EC2Connection(AWSQueryConnection):
:param max_results: The maximum number of paginated items
per response.
:type next_token: str
:param next_token: The next set of rows to return. This should
be the value of the ``next_token`` attribute from a previous
call to ``get_spot_price_history``.
: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 tuples containing price and timestamp.
"""
@@ -1357,6 +1374,10 @@ class EC2Connection(AWSQueryConnection):
params['DryRun'] = 'true'
if max_results is not None:
params['MaxResults'] = max_results
if next_token:
params['NextToken'] = next_token
if filters:
self.build_filter_params(params, filters)
return self.get_list('DescribeSpotPriceHistory', params,
[('item', SpotPriceHistory)], verb='POST')
@@ -1424,6 +1445,8 @@ class EC2Connection(AWSQueryConnection):
* m1.medium
* m1.large
* m1.xlarge
* m3.medium
* m3.large
* m3.xlarge
* m3.2xlarge
* c1.medium
@@ -1814,6 +1837,37 @@ class EC2Connection(AWSQueryConnection):
return self.get_status('AssignPrivateIpAddresses', params, verb='POST')
def _associate_address(self, status, instance_id=None, public_ip=None,
allocation_id=None, network_interface_id=None,
private_ip_address=None, allow_reassociation=False,
dry_run=False):
params = {}
if instance_id is not None:
params['InstanceId'] = instance_id
elif network_interface_id is not None:
params['NetworkInterfaceId'] = network_interface_id
# Allocation id trumps public ip in order to associate with VPCs
if allocation_id is not None:
params['AllocationId'] = allocation_id
elif public_ip is not None:
params['PublicIp'] = public_ip
if private_ip_address is not None:
params['PrivateIpAddress'] = private_ip_address
if allow_reassociation:
params['AllowReassociation'] = 'true'
if dry_run:
params['DryRun'] = 'true'
if status:
return self.get_status('AssociateAddress', params, verb='POST')
else:
return self.get_object('AssociateAddress', params, Address,
verb='POST')
def associate_address(self, instance_id=None, public_ip=None,
allocation_id=None, network_interface_id=None,
private_ip_address=None, allow_reassociation=False,
@@ -1856,27 +1910,59 @@ class EC2Connection(AWSQueryConnection):
:rtype: bool
:return: True if successful
"""
params = {}
if instance_id is not None:
params['InstanceId'] = instance_id
elif network_interface_id is not None:
params['NetworkInterfaceId'] = network_interface_id
return self._associate_address(True, instance_id=instance_id,
public_ip=public_ip, allocation_id=allocation_id,
network_interface_id=network_interface_id,
private_ip_address=private_ip_address,
allow_reassociation=allow_reassociation, dry_run=dry_run)
if public_ip is not None:
params['PublicIp'] = public_ip
elif allocation_id is not None:
params['AllocationId'] = allocation_id
def associate_address_object(self, instance_id=None, public_ip=None,
allocation_id=None, network_interface_id=None,
private_ip_address=None, allow_reassociation=False,
dry_run=False):
"""
Associate an Elastic IP address with a currently running instance.
This requires one of ``public_ip`` or ``allocation_id`` depending
on if you're associating a VPC address or a plain EC2 address.
if private_ip_address is not None:
params['PrivateIpAddress'] = private_ip_address
When using an Allocation ID, make sure to pass ``None`` for ``public_ip``
as EC2 expects a single parameter and if ``public_ip`` is passed boto
will preference that instead of ``allocation_id``.
if allow_reassociation:
params['AllowReassociation'] = 'true'
:type instance_id: string
:param instance_id: The ID of the instance
if dry_run:
params['DryRun'] = 'true'
:type public_ip: string
:param public_ip: The public IP address for EC2 based allocations.
return self.get_status('AssociateAddress', params, verb='POST')
:type allocation_id: string
:param allocation_id: The allocation ID for a VPC-based elastic IP.
:type network_interface_id: string
:param network_interface_id: The network interface ID to which
elastic IP is to be assigned to
:type private_ip_address: string
:param private_ip_address: The primary or secondary private IP address
to associate with the Elastic IP address.
:type allow_reassociation: bool
:param allow_reassociation: Specify this option to allow an Elastic IP
address that is already associated with another network interface
or instance to be re-associated with the specified instance or
interface.
:type dry_run: bool
:param dry_run: Set to True if the operation should not actually run.
:rtype: class:`boto.ec2.address.Address`
:return: The associated address instance
"""
return self._associate_address(False, instance_id=instance_id,
public_ip=public_ip, allocation_id=allocation_id,
network_interface_id=network_interface_id,
private_ip_address=private_ip_address,
allow_reassociation=allow_reassociation, dry_run=dry_run)
def disassociate_address(self, public_ip=None, association_id=None,
dry_run=False):
@@ -1897,10 +1983,12 @@ class EC2Connection(AWSQueryConnection):
"""
params = {}
if public_ip is not None:
params['PublicIp'] = public_ip
elif association_id is not None:
# If there is an association id it trumps public ip
# in order to successfully dissassociate with a VPC elastic ip
if association_id is not None:
params['AssociationId'] = association_id
elif public_ip is not None:
params['PublicIp'] = public_ip
if dry_run:
params['DryRun'] = 'true'
@@ -4236,15 +4324,15 @@ class EC2Connection(AWSQueryConnection):
params['DryRun'] = 'true'
return self.get_status('DeleteNetworkInterface', params, verb='POST')
def get_all_vmtypes(self):
def get_all_instance_types(self):
"""
Get all vmtypes available on this cloud (eucalyptus specific)
Get all instance_types available on this cloud (eucalyptus specific)
:rtype: list of :class:`boto.ec2.vmtype.VmType`
:return: The requested VmType objects
:rtype: list of :class:`boto.ec2.instancetype.InstanceType`
:return: The requested InstanceType objects
"""
params = {}
return self.get_list('DescribeVmTypes', params, [('euca:item', VmType)], verb='POST')
return self.get_list('DescribeInstanceTypes', params, [('item', InstanceType)], verb='POST')
def copy_image(self, source_region, source_image_id, name=None,
description=None, client_token=None, dry_run=False):

View File

@@ -31,21 +31,10 @@ from boto.ec2.elb.loadbalancer import LoadBalancer, LoadBalancerZones
from boto.ec2.elb.instancestate import InstanceState
from boto.ec2.elb.healthcheck import HealthCheck
from boto.ec2.elb.listelement import ListElement
from boto.regioninfo import RegionInfo
from boto.regioninfo import RegionInfo, get_regions, load_regions
import boto
RegionData = {
'us-east-1': 'elasticloadbalancing.us-east-1.amazonaws.com',
'us-gov-west-1': 'elasticloadbalancing.us-gov-west-1.amazonaws.com',
'us-west-1': 'elasticloadbalancing.us-west-1.amazonaws.com',
'us-west-2': 'elasticloadbalancing.us-west-2.amazonaws.com',
'sa-east-1': 'elasticloadbalancing.sa-east-1.amazonaws.com',
'eu-west-1': 'elasticloadbalancing.eu-west-1.amazonaws.com',
'ap-northeast-1': 'elasticloadbalancing.ap-northeast-1.amazonaws.com',
'ap-southeast-1': 'elasticloadbalancing.ap-southeast-1.amazonaws.com',
'ap-southeast-2': 'elasticloadbalancing.ap-southeast-2.amazonaws.com',
'cn-north-1': 'elasticloadbalancing.cn-north-1.amazonaws.com.cn',
}
RegionData = load_regions().get('elasticloadbalancing', {})
def regions():
@@ -55,13 +44,7 @@ def regions():
:rtype: list
:return: A list of :class:`boto.RegionInfo` instances
"""
regions = []
for region_name in RegionData:
region = RegionInfo(name=region_name,
endpoint=RegionData[region_name],
connection_cls=ELBConnection)
regions.append(region)
return regions
return get_regions('elasticloadbalancing', connection_cls=ELBConnection)
def connect_to_region(region_name, **kw_params):
@@ -92,7 +75,7 @@ class ELBConnection(AWSQueryConnection):
is_secure=True, port=None, proxy=None, proxy_port=None,
proxy_user=None, proxy_pass=None, debug=0,
https_connection_factory=None, region=None, path='/',
security_token=None, validate_certs=True):
security_token=None, validate_certs=True, profile_name=None):
"""
Init method to create a new connection to EC2 Load Balancing Service.
@@ -110,13 +93,14 @@ class ELBConnection(AWSQueryConnection):
self.region.endpoint, debug,
https_connection_factory, path,
security_token,
validate_certs=validate_certs)
validate_certs=validate_certs,
profile_name=profile_name)
def _required_auth_capability(self):
return ['ec2']
def build_list_params(self, params, items, label):
if isinstance(items, str):
if isinstance(items, basestring):
items = [items]
for index, item in enumerate(items):
params[label % (index + 1)] = item
@@ -401,6 +385,7 @@ class ELBConnection(AWSQueryConnection):
:param attribute: The attribute you wish to change.
* crossZoneLoadBalancing - Boolean (true)
* accessLog - :py:class:`AccessLogAttribute` instance
:type value: string
:param value: The new value for the attribute
@@ -421,6 +406,15 @@ class ELBConnection(AWSQueryConnection):
if attribute.lower() == 'crosszoneloadbalancing':
params['LoadBalancerAttributes.CrossZoneLoadBalancing.Enabled'
] = value
elif attribute.lower() == 'accesslog':
params['LoadBalancerAttributes.AccessLog.Enabled'] = \
value.enabled and 'true' or 'false'
params['LoadBalancerAttributes.AccessLog.S3BucketName'] = \
value.s3_bucket_name
params['LoadBalancerAttributes.AccessLog.S3BucketPrefix'] = \
value.s3_bucket_prefix
params['LoadBalancerAttributes.AccessLog.EmitInterval'] = \
value.emit_interval
else:
raise ValueError('InvalidAttribute', attribute)
return self.get_status('ModifyLoadBalancerAttributes', params,

View File

@@ -40,6 +40,41 @@ class CrossZoneLoadBalancingAttribute(object):
else:
self.enabled = False
class AccessLogAttribute(object):
"""
Represents the AccessLog segment of ELB attributes.
"""
def __init__(self, connection=None):
self.enabled = None
self.s3_bucket_name = None
self.s3_bucket_prefix = None
self.emit_interval = None
def __repr__(self):
return 'AccessLog(%s, %s, %s, %s)' % (
self.enabled,
self.s3_bucket_name,
self.s3_bucket_prefix,
self.emit_interval
)
def startElement(self, name, attrs, connection):
pass
def endElement(self, name, value, connection):
if name == 'Enabled':
if value.lower() == 'true':
self.enabled = True
else:
self.enabled = False
elif name == 'S3BucketName':
self.s3_bucket_name = value
elif name == 'S3BucketPrefix':
self.s3_bucket_prefix = value
elif name == 'EmitInterval':
self.emit_interval = int(value)
class LbAttributes(object):
"""
Represents the Attributes of an Elastic Load Balancer.
@@ -48,14 +83,18 @@ class LbAttributes(object):
self.connection = connection
self.cross_zone_load_balancing = CrossZoneLoadBalancingAttribute(
self.connection)
self.access_log = AccessLogAttribute(self.connection)
def __repr__(self):
return 'LbAttributes(%s)' % (
repr(self.cross_zone_load_balancing))
return 'LbAttributes(%s, %s)' % (
repr(self.cross_zone_load_balancing),
repr(self.access_log))
def startElement(self, name, attrs, connection):
if name == 'CrossZoneLoadBalancing':
return self.cross_zone_load_balancing
if name == 'AccessLog':
return self.access_log
def endElement(self, name, value, connection):
pass

View File

@@ -186,7 +186,7 @@ class LoadBalancer(object):
:param zones: The name of the zone(s) to add.
"""
if isinstance(zones, str) or isinstance(zones, unicode):
if isinstance(zones, basestring):
zones = [zones]
new_zones = self.connection.enable_availability_zones(self.name, zones)
self.availability_zones = new_zones
@@ -199,7 +199,7 @@ class LoadBalancer(object):
:param zones: The name of the zone(s) to add.
"""
if isinstance(zones, str) or isinstance(zones, unicode):
if isinstance(zones, basestring):
zones = [zones]
new_zones = self.connection.disable_availability_zones(self.name, zones)
self.availability_zones = new_zones
@@ -266,7 +266,7 @@ class LoadBalancer(object):
to add to this load balancer.
"""
if isinstance(instances, str) or isinstance(instances, unicode):
if isinstance(instances, basestring):
instances = [instances]
new_instances = self.connection.register_instances(self.name,
instances)
@@ -281,7 +281,7 @@ class LoadBalancer(object):
to remove from this load balancer.
"""
if isinstance(instances, str) or isinstance(instances, unicode):
if isinstance(instances, basestring):
instances = [instances]
new_instances = self.connection.deregister_instances(self.name,
instances)
@@ -324,7 +324,7 @@ class LoadBalancer(object):
listeners)
def create_listener(self, inPort, outPort=None, proto="tcp"):
if outPort == None:
if outPort is None:
outPort = inPort
return self.create_listeners([(inPort, outPort, proto)])
@@ -380,7 +380,7 @@ class LoadBalancer(object):
:param subnets: The name of the subnet(s) to add.
"""
if isinstance(subnets, str) or isinstance(subnets, unicode):
if isinstance(subnets, basestring):
subnets = [subnets]
new_subnets = self.connection.attach_lb_to_subnets(self.name, subnets)
self.subnets = new_subnets
@@ -393,7 +393,7 @@ class LoadBalancer(object):
:param subnets: The name of the subnet(s) to detach.
"""
if isinstance(subnets, str) or isinstance(subnets, unicode):
if isinstance(subnets, basestring):
subnets = [subnets]
new_subnets = self.connection.detach_lb_from_subnets(self.name, subnets)
self.subnets = new_subnets
@@ -408,8 +408,7 @@ class LoadBalancer(object):
:param security_groups: The name of the security group(s) to add.
"""
if isinstance(security_groups, str) or \
isinstance(security_groups, unicode):
if isinstance(security_groups, basestring):
security_groups = [security_groups]
new_sgs = self.connection.apply_security_groups_to_lb(
self.name, security_groups)

View File

@@ -208,6 +208,8 @@ class Image(TaggedEC2Object):
* m1.medium
* m1.large
* m1.xlarge
* m3.medium
* m3.large
* m3.xlarge
* m3.2xlarge
* c1.medium

View File

@@ -0,0 +1,59 @@
# Copyright (c) 2006-2009 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.
from boto.ec2.ec2object import EC2Object
class InstanceType(EC2Object):
"""
Represents an EC2 VM Type
:ivar name: The name of the vm type
:ivar cores: The number of cpu cores for this vm type
:ivar memory: The amount of memory in megabytes for this vm type
:ivar disk: The amount of disk space in gigabytes for this vm type
"""
def __init__(self, connection=None, name=None, cores=None,
memory=None, disk=None):
super(InstanceType, self).__init__(connection)
self.connection = connection
self.name = name
self.cores = cores
self.memory = memory
self.disk = disk
def __repr__(self):
return 'InstanceType:%s-%s,%s,%s' % (self.name, self.cores,
self.memory, self.disk)
def endElement(self, name, value, connection):
if name == 'name':
self.name = value
elif name == 'cpu':
self.cores = value
elif name == 'disk':
self.disk = value
elif name == 'memory':
self.memory = value
else:
setattr(self, name, value)

View File

@@ -28,7 +28,8 @@ class EC2RegionInfo(RegionInfo):
Represents an EC2 Region
"""
def __init__(self, connection=None, name=None, endpoint=None):
def __init__(self, connection=None, name=None, endpoint=None,
connection_cls=None):
from boto.ec2.connection import EC2Connection
super(EC2RegionInfo, self).__init__(connection, name, endpoint,
EC2Connection)