summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lindsley <daniel@toastdriven.com>2013-09-12 15:23:35 -0700
committerDaniel Lindsley <daniel@toastdriven.com>2013-09-12 15:23:35 -0700
commitdd7774c1f5e3eb5dbf77438c2c58e515a34be171 (patch)
treeb5801d42147426d5a30562425fa0f4a1ea4812f5
parent6c5a394670aef55435e24423fd26e56a0b3b3489 (diff)
parent530b1aa08e03a28a1c789db45c1936bc0d56344f (diff)
downloadboto-dd7774c1f5e3eb5dbf77438c2c58e515a34be171.tar.gz
Merge branch 'ec2-dry-run' into develop
-rw-r--r--boto/ec2/address.py33
-rw-r--r--boto/ec2/connection.py786
-rw-r--r--boto/ec2/ec2object.py20
-rw-r--r--boto/ec2/image.py70
-rw-r--r--boto/ec2/instance.py96
-rw-r--r--boto/ec2/keypair.py18
-rw-r--r--boto/ec2/networkinterface.py7
-rw-r--r--boto/ec2/placementgroup.py11
-rw-r--r--boto/ec2/reservedinstance.py8
-rw-r--r--boto/ec2/securitygroup.py67
-rw-r--r--boto/ec2/snapshot.py61
-rw-r--r--boto/ec2/spotdatafeedsubscription.py10
-rw-r--r--boto/ec2/spotinstancerequest.py7
-rw-r--r--boto/ec2/volume.py52
-rw-r--r--boto/vpc/__init__.py295
-rw-r--r--boto/vpc/vpc.py7
-rw-r--r--boto/vpc/vpnconnection.py7
-rw-r--r--boto/vpc/vpngateway.py16
-rw-r--r--tests/integration/ec2/test_connection.py51
19 files changed, 1286 insertions, 336 deletions
diff --git a/boto/ec2/address.py b/boto/ec2/address.py
index 9eadfaa3..27608a4a 100644
--- a/boto/ec2/address.py
+++ b/boto/ec2/address.py
@@ -71,33 +71,50 @@ class Address(EC2Object):
else:
setattr(self, name, value)
- def release(self):
+ def release(self, dry_run=False):
"""
Free up this Elastic IP address.
:see: :meth:`boto.ec2.connection.EC2Connection.release_address`
"""
if self.allocation_id:
- return self.connection.release_address(None, self.allocation_id)
+ return self.connection.release_address(
+ None,
+ self.allocation_id,
+ dry_run=dry_run)
else:
- return self.connection.release_address(self.public_ip)
+ return self.connection.release_address(
+ self.public_ip,
+ dry_run=dry_run
+ )
delete = release
- def associate(self, instance_id):
+ def associate(self, instance_id, dry_run=False):
"""
Associate this Elastic IP address with a currently running instance.
:see: :meth:`boto.ec2.connection.EC2Connection.associate_address`
"""
- return self.connection.associate_address(instance_id, self.public_ip)
+ return self.connection.associate_address(
+ instance_id,
+ self.public_ip,
+ dry_run=dry_run
+ )
- def disassociate(self):
+ def disassociate(self, dry_run=False):
"""
Disassociate this Elastic IP address from a currently running instance.
:see: :meth:`boto.ec2.connection.EC2Connection.disassociate_address`
"""
if self.association_id:
- return self.connection.disassociate_address(None, self.association_id)
+ return self.connection.disassociate_address(
+ None,
+ self.association_id,
+ dry_run=dry_run
+ )
else:
- return self.connection.disassociate_address(self.public_ip)
+ return self.connection.disassociate_address(
+ self.public_ip,
+ dry_run=dry_run
+ )
diff --git a/boto/ec2/connection.py b/boto/ec2/connection.py
index 9d9b1ae1..729ffdde 100644
--- a/boto/ec2/connection.py
+++ b/boto/ec2/connection.py
@@ -133,7 +133,7 @@ class EC2Connection(AWSQueryConnection):
# Image methods
def get_all_images(self, image_ids=None, owners=None,
- executable_by=None, filters=None):
+ executable_by=None, filters=None, dry_run=False):
"""
Retrieve all the EC2 images available on your account.
@@ -158,6 +158,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
@@ -170,10 +173,12 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, executable_by, 'ExecutableBy')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
- def get_all_kernels(self, kernel_ids=None, owners=None):
+ def get_all_kernels(self, kernel_ids=None, owners=None, dry_run=False):
"""
Retrieve all the EC2 kernels available on your account.
Constructs a filter to allow the processing to happen server side.
@@ -184,6 +189,9 @@ class EC2Connection(AWSQueryConnection):
:type owners: list
:param owners: A list of owner IDs
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
@@ -194,10 +202,12 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, owners, 'Owner')
filter = {'image-type': 'kernel'}
self.build_filter_params(params, filter)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
- def get_all_ramdisks(self, ramdisk_ids=None, owners=None):
+ def get_all_ramdisks(self, ramdisk_ids=None, owners=None, dry_run=False):
"""
Retrieve all the EC2 ramdisks available on your account.
Constructs a filter to allow the processing to happen server side.
@@ -208,6 +218,9 @@ class EC2Connection(AWSQueryConnection):
:type owners: list
:param owners: A list of owner IDs
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.image.Image`
"""
@@ -218,27 +231,33 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, owners, 'Owner')
filter = {'image-type': 'ramdisk'}
self.build_filter_params(params, filter)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeImages', params,
[('item', Image)], verb='POST')
- def get_image(self, image_id):
+ def get_image(self, image_id, dry_run=False):
"""
Shortcut method to retrieve a specific image (AMI).
:type image_id: string
:param image_id: the ID of the Image to retrieve
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.image.Image`
:return: The EC2 Image specified or None if the image is not found
"""
try:
- return self.get_all_images(image_ids=[image_id])[0]
+ return self.get_all_images(image_ids=[image_id], dry_run=dry_run)[0]
except IndexError: # None of those images available
return None
def register_image(self, name=None, description=None, image_location=None,
architecture=None, kernel_id=None, ramdisk_id=None,
- root_device_name=None, block_device_map=None):
+ root_device_name=None, block_device_map=None,
+ dry_run=False):
"""
Register an image.
@@ -268,6 +287,9 @@ class EC2Connection(AWSQueryConnection):
:param block_device_map: A BlockDeviceMapping data structure
describing the EBS volumes associated with the Image.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: string
:return: The new image id
"""
@@ -288,11 +310,13 @@ class EC2Connection(AWSQueryConnection):
params['RootDeviceName'] = root_device_name
if block_device_map:
block_device_map.build_list_params(params)
+ if dry_run:
+ params['DryRun'] = 'true'
rs = self.get_object('RegisterImage', params, ResultSet, verb='POST')
image_id = getattr(rs, 'imageId', None)
return image_id
- def deregister_image(self, image_id, delete_snapshot=False):
+ def deregister_image(self, image_id, delete_snapshot=False, dry_run=False):
"""
Unregister an AMI.
@@ -303,6 +327,9 @@ class EC2Connection(AWSQueryConnection):
:param delete_snapshot: Set to True if we should delete the
snapshot associated with an EBS volume mounted at /dev/sda1
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -313,15 +340,19 @@ class EC2Connection(AWSQueryConnection):
if key == "/dev/sda1":
snapshot_id = image.block_device_mapping[key].snapshot_id
break
-
+ params = {
+ 'ImageId': image_id,
+ }
+ if dry_run:
+ params['DryRun'] = 'true'
result = self.get_status('DeregisterImage',
- {'ImageId':image_id}, verb='POST')
+ params, verb='POST')
if result and snapshot_id:
return result and self.delete_snapshot(snapshot_id)
return result
def create_image(self, instance_id, name,
- description=None, no_reboot=False):
+ description=None, no_reboot=False, dry_run=False):
"""
Will create an AMI from the instance in the running or stopped
state.
@@ -343,6 +374,9 @@ class EC2Connection(AWSQueryConnection):
responsibility of maintaining file system integrity is
left to the owner of the instance.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: string
:return: The new image id
"""
@@ -352,12 +386,15 @@ class EC2Connection(AWSQueryConnection):
params['Description'] = description
if no_reboot:
params['NoReboot'] = 'true'
+ if dry_run:
+ params['DryRun'] = 'true'
img = self.get_object('CreateImage', params, Image, verb='POST')
return img.id
# ImageAttribute methods
- def get_image_attribute(self, image_id, attribute='launchPermission'):
+ def get_image_attribute(self, image_id, attribute='launchPermission',
+ dry_run=False):
"""
Gets an attribute from an image.
@@ -371,18 +408,23 @@ class EC2Connection(AWSQueryConnection):
* productCodes
* blockDeviceMapping
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.image.ImageAttribute`
:return: An ImageAttribute object representing the value of the
attribute requested
"""
params = {'ImageId': image_id,
'Attribute': attribute}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeImageAttribute', params,
ImageAttribute, verb='POST')
def modify_image_attribute(self, image_id, attribute='launchPermission',
operation='add', user_ids=None, groups=None,
- product_codes=None):
+ product_codes=None, dry_run=False):
"""
Changes an attribute of an image.
@@ -406,6 +448,10 @@ class EC2Connection(AWSQueryConnection):
:param product_codes: Amazon DevPay product code. Currently only one
product code can be associated with an AMI. Once
set, the product code cannot be changed or reset.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'ImageId': image_id,
'Attribute': attribute,
@@ -416,9 +462,12 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, groups, 'UserGroup')
if product_codes:
self.build_list_params(params, product_codes, 'ProductCode')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ModifyImageAttribute', params, verb='POST')
- def reset_image_attribute(self, image_id, attribute='launchPermission'):
+ def reset_image_attribute(self, image_id, attribute='launchPermission',
+ dry_run=False):
"""
Resets an attribute of an AMI to its default value.
@@ -428,16 +477,21 @@ class EC2Connection(AWSQueryConnection):
:type attribute: string
:param attribute: The attribute to reset
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: Whether the operation succeeded or not
"""
params = {'ImageId': image_id,
'Attribute': attribute}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ResetImageAttribute', params, verb='POST')
# Instance methods
- def get_all_instances(self, instance_ids=None, filters=None):
+ def get_all_instances(self, instance_ids=None, filters=None, dry_run=False):
"""
Retrieve all the instance reservations associated with your account.
@@ -459,6 +513,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instance.Reservation`
@@ -467,9 +524,10 @@ class EC2Connection(AWSQueryConnection):
'replaced with get_all_reservations.'),
PendingDeprecationWarning)
return self.get_all_reservations(instance_ids=instance_ids,
- filters=filters)
+ filters=filters, dry_run=dry_run)
- def get_only_instances(self, instance_ids=None, filters=None):
+ def get_only_instances(self, instance_ids=None, filters=None,
+ dry_run=False):
# A future release should rename this method to get_all_instances
# and make get_only_instances an alias for that.
"""
@@ -486,15 +544,20 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instance.Instance`
"""
reservations = self.get_all_reservations(instance_ids=instance_ids,
- filters=filters)
+ filters=filters,
+ dry_run=dry_run)
return [instance for reservation in reservations
for instance in reservation.instances]
- def get_all_reservations(self, instance_ids=None, filters=None):
+ def get_all_reservations(self, instance_ids=None, filters=None,
+ dry_run=False):
"""
Retrieve all the instance reservations associated with your account.
@@ -509,6 +572,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instance.Reservation`
"""
@@ -525,12 +591,14 @@ class EC2Connection(AWSQueryConnection):
"by group name use the 'group-name' filter instead.",
UserWarning)
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeInstances', params,
[('item', Reservation)], verb='POST')
def get_all_instance_status(self, instance_ids=None,
max_results=None, next_token=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Retrieve all the instances in your account scheduled for maintenance.
@@ -555,6 +623,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of instances that have maintenance scheduled.
"""
@@ -567,6 +638,8 @@ class EC2Connection(AWSQueryConnection):
params['NextToken'] = next_token
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeInstanceStatus', params,
InstanceStatusSet, verb='POST')
@@ -584,7 +657,8 @@ class EC2Connection(AWSQueryConnection):
security_group_ids=None,
additional_info=None, instance_profile_name=None,
instance_profile_arn=None, tenancy=None,
- ebs_optimized=False, network_interfaces=None):
+ ebs_optimized=False, network_interfaces=None,
+ dry_run=False):
"""
Runs an image on EC2.
@@ -715,6 +789,9 @@ class EC2Connection(AWSQueryConnection):
:param network_interfaces: A list of
:class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Reservation
:return: The :class:`boto.ec2.instance.Reservation` associated with
the request for machines
@@ -781,26 +858,33 @@ class EC2Connection(AWSQueryConnection):
params['EbsOptimized'] = 'true'
if network_interfaces:
network_interfaces.build_list_params(params)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('RunInstances', params, Reservation,
verb='POST')
- def terminate_instances(self, instance_ids=None):
+ def terminate_instances(self, instance_ids=None, dry_run=False):
"""
Terminate the instances specified
:type instance_ids: list
:param instance_ids: A list of strings of the Instance IDs to terminate
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of the instances terminated
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('TerminateInstances', params,
[('item', Instance)], verb='POST')
- def stop_instances(self, instance_ids=None, force=False):
+ def stop_instances(self, instance_ids=None, force=False, dry_run=False):
"""
Stop the instances specified
@@ -810,6 +894,9 @@ class EC2Connection(AWSQueryConnection):
:type force: bool
:param force: Forces the instance to stop
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of the instances stopped
"""
@@ -818,62 +905,88 @@ class EC2Connection(AWSQueryConnection):
params['Force'] = 'true'
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('StopInstances', params,
[('item', Instance)], verb='POST')
- def start_instances(self, instance_ids=None):
+ def start_instances(self, instance_ids=None, dry_run=False):
"""
Start the instances specified
:type instance_ids: list
:param instance_ids: A list of strings of the Instance IDs to start
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of the instances started
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('StartInstances', params,
[('item', Instance)], verb='POST')
- def get_console_output(self, instance_id):
+ def get_console_output(self, instance_id, dry_run=False):
"""
Retrieves the console output for the specified instance.
:type instance_id: string
:param instance_id: The instance ID of a running instance on the cloud.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.instance.ConsoleOutput`
:return: The console output as a ConsoleOutput object
"""
params = {}
self.build_list_params(params, [instance_id], 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('GetConsoleOutput', params,
ConsoleOutput, verb='POST')
- def reboot_instances(self, instance_ids=None):
+ def reboot_instances(self, instance_ids=None, dry_run=False):
"""
Reboot the specified instances.
:type instance_ids: list
:param instance_ids: The instances to terminate and reboot
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {}
if instance_ids:
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('RebootInstances', params)
- def confirm_product_instance(self, product_code, instance_id):
+ def confirm_product_instance(self, product_code, instance_id,
+ dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {'ProductCode': product_code,
'InstanceId': instance_id}
+ if dry_run:
+ params['DryRun'] = 'true'
rs = self.get_object('ConfirmProductInstance', params,
ResultSet, verb='POST')
return (rs.status, rs.ownerId)
# InstanceAttribute methods
- def get_instance_attribute(self, instance_id, attribute):
+ def get_instance_attribute(self, instance_id, attribute, dry_run=False):
"""
Gets an attribute from an instance.
@@ -897,6 +1010,9 @@ class EC2Connection(AWSQueryConnection):
* groupSet
* ebsOptimized
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.image.InstanceAttribute`
:return: An InstanceAttribute object representing the value of the
attribute requested
@@ -904,11 +1020,13 @@ class EC2Connection(AWSQueryConnection):
params = {'InstanceId': instance_id}
if attribute:
params['Attribute'] = attribute
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeInstanceAttribute', params,
InstanceAttribute, verb='POST')
def modify_network_interface_attribute(self, interface_id, attr, value,
- attachment_id=None):
+ attachment_id=None, dry_run=False):
"""
Changes an attribute of a network interface.
@@ -935,6 +1053,10 @@ class EC2Connection(AWSQueryConnection):
:type attachment_id: string
:param attachment_id: If you're modifying DeleteOnTermination you must
specify the attachment_id.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
bool_reqs = (
'deleteontermination',
@@ -970,10 +1092,13 @@ class EC2Connection(AWSQueryConnection):
else:
raise ValueError('Unknown attribute "%s"' % (attr,))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status(
'ModifyNetworkInterfaceAttribute', params, verb='POST')
- def modify_instance_attribute(self, instance_id, attribute, value):
+ def modify_instance_attribute(self, instance_id, attribute, value,
+ dry_run=False):
"""
Changes an attribute of an instance
@@ -997,6 +1122,9 @@ class EC2Connection(AWSQueryConnection):
:type value: string
:param value: The new value for the attribute
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: Whether the operation succeeded or not
"""
@@ -1030,9 +1158,11 @@ class EC2Connection(AWSQueryConnection):
attribute = attribute[0].upper() + attribute[1:]
params['%s.Value' % attribute] = value
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ModifyInstanceAttribute', params, verb='POST')
- def reset_instance_attribute(self, instance_id, attribute):
+ def reset_instance_attribute(self, instance_id, attribute, dry_run=False):
"""
Resets an attribute of an instance to its default value.
@@ -1043,17 +1173,22 @@ class EC2Connection(AWSQueryConnection):
:param attribute: The attribute to reset. Valid values are:
kernel|ramdisk
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: Whether the operation succeeded or not
"""
params = {'InstanceId': instance_id,
'Attribute': attribute}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ResetInstanceAttribute', params, verb='POST')
# Spot Instances
def get_all_spot_instance_requests(self, request_ids=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Retrieve all the spot instances requests associated with your account.
@@ -1068,6 +1203,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of
:class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
@@ -1085,12 +1223,14 @@ class EC2Connection(AWSQueryConnection):
"group name. Please update your filters accordingly.",
UserWarning)
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeSpotInstanceRequests', params,
[('item', SpotInstanceRequest)], verb='POST')
def get_spot_price_history(self, start_time=None, end_time=None,
instance_type=None, product_description=None,
- availability_zone=None):
+ availability_zone=None, dry_run=False):
"""
Retrieve the recent history of spot instances pricing.
@@ -1121,6 +1261,9 @@ class EC2Connection(AWSQueryConnection):
should be returned. If not specified, data for all
availability zones will be returned.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list tuples containing price and timestamp.
"""
@@ -1135,6 +1278,8 @@ class EC2Connection(AWSQueryConnection):
params['ProductDescription'] = product_description
if availability_zone:
params['AvailabilityZone'] = availability_zone
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeSpotPriceHistory', params,
[('item', SpotPriceHistory)], verb='POST')
@@ -1152,7 +1297,7 @@ class EC2Connection(AWSQueryConnection):
instance_profile_name=None,
security_group_ids=None,
ebs_optimized=False,
- network_interfaces=None):
+ network_interfaces=None, dry_run=False):
"""
Request instances on the spot market at a particular price.
@@ -1259,6 +1404,9 @@ class EC2Connection(AWSQueryConnection):
:param network_interfaces: A list of
:class:`boto.ec2.networkinterface.NetworkInterfaceSpecification`
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Reservation
:return: The :class:`boto.ec2.spotinstancerequest.SpotInstanceRequest`
associated with the request for machines
@@ -1324,38 +1472,51 @@ class EC2Connection(AWSQueryConnection):
params['%s.EbsOptimized' % ls] = 'true'
if network_interfaces:
network_interfaces.build_list_params(params, prefix=ls + '.')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('RequestSpotInstances', params,
[('item', SpotInstanceRequest)],
verb='POST')
- def cancel_spot_instance_requests(self, request_ids):
+ def cancel_spot_instance_requests(self, request_ids, dry_run=False):
"""
Cancel the specified Spot Instance Requests.
:type request_ids: list
:param request_ids: A list of strings of the Request IDs to terminate
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of the instances terminated
"""
params = {}
if request_ids:
self.build_list_params(params, request_ids, 'SpotInstanceRequestId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('CancelSpotInstanceRequests', params,
[('item', Instance)], verb='POST')
- def get_spot_datafeed_subscription(self):
+ def get_spot_datafeed_subscription(self, dry_run=False):
"""
Return the current spot instance data feed subscription
associated with this account, if any.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
:return: The datafeed subscription object or None
"""
+ params = {}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeSpotDatafeedSubscription',
- None, SpotDatafeedSubscription, verb='POST')
+ params, SpotDatafeedSubscription, verb='POST')
- def create_spot_datafeed_subscription(self, bucket, prefix):
+ def create_spot_datafeed_subscription(self, bucket, prefix, dry_run=False):
"""
Create a spot instance datafeed subscription for this account.
@@ -1369,29 +1530,40 @@ class EC2Connection(AWSQueryConnection):
:param prefix: An optional prefix that will be pre-pended to all
data files written to the bucket.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.spotdatafeedsubscription.SpotDatafeedSubscription`
:return: The datafeed subscription object or None
"""
params = {'Bucket': bucket}
if prefix:
params['Prefix'] = prefix
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateSpotDatafeedSubscription',
params, SpotDatafeedSubscription, verb='POST')
- def delete_spot_datafeed_subscription(self):
+ def delete_spot_datafeed_subscription(self, dry_run=False):
"""
Delete the current spot instance data feed subscription
associated with this account
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
+ params = {}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteSpotDatafeedSubscription',
- None, verb='POST')
+ params, verb='POST')
# Zone methods
- def get_all_zones(self, zones=None, filters=None):
+ def get_all_zones(self, zones=None, filters=None, dry_run=False):
"""
Get all Availability Zones associated with the current region.
@@ -1410,6 +1582,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.zone.Zone`
:return: The requested Zone objects
"""
@@ -1418,12 +1593,15 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, zones, 'ZoneName')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeAvailabilityZones', params,
[('item', Zone)], verb='POST')
# Address methods
- def get_all_addresses(self, addresses=None, filters=None, allocation_ids=None):
+ def get_all_addresses(self, addresses=None, filters=None,
+ allocation_ids=None, dry_run=False):
"""
Get all EIP's associated with the current credentials.
@@ -1447,6 +1625,9 @@ class EC2Connection(AWSQueryConnection):
present, only the Addresses associated with the given
allocation IDs will be returned.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.address.Address`
:return: The requested Address objects
"""
@@ -1457,9 +1638,11 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, allocation_ids, 'AllocationId')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeAddresses', params, [('item', Address)], verb='POST')
- def allocate_address(self, domain=None):
+ def allocate_address(self, domain=None, dry_run=False):
"""
Allocate a new Elastic IP address and associate it with your account.
@@ -1468,6 +1651,9 @@ class EC2Connection(AWSQueryConnection):
will be allocated to VPC . Will return address object with
allocation_id.
+ :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 newly allocated Address
"""
@@ -1476,12 +1662,15 @@ class EC2Connection(AWSQueryConnection):
if domain is not None:
params['Domain'] = domain
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_object('AllocateAddress', params, Address, verb='POST')
def assign_private_ip_addresses(self, network_interface_id=None,
private_ip_addresses=None,
secondary_private_ip_address_count=None,
- allow_reassignment=False):
+ allow_reassignment=False, dry_run=False):
"""
Assigns one or more secondary private IP addresses to a network
interface in Amazon VPC.
@@ -1504,6 +1693,9 @@ class EC2Connection(AWSQueryConnection):
that is already assigned to another network interface or instance
to be reassigned to the specified network interface.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -1522,11 +1714,15 @@ class EC2Connection(AWSQueryConnection):
if allow_reassignment:
params['AllowReassignment'] = 'true'
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('AssignPrivateIpAddresses', params, 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):
+ 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
@@ -1559,6 +1755,9 @@ class EC2Connection(AWSQueryConnection):
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: bool
:return: True if successful
"""
@@ -1579,9 +1778,13 @@ class EC2Connection(AWSQueryConnection):
if allow_reassociation:
params['AllowReassociation'] = 'true'
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('AssociateAddress', params, verb='POST')
- def disassociate_address(self, public_ip=None, association_id=None):
+ def disassociate_address(self, public_ip=None, association_id=None,
+ dry_run=False):
"""
Disassociate an Elastic IP address from a currently running instance.
@@ -1591,6 +1794,9 @@ class EC2Connection(AWSQueryConnection):
:type association_id: string
:param association_id: The association ID for a VPC based elastic ip.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -1601,9 +1807,13 @@ class EC2Connection(AWSQueryConnection):
elif association_id is not None:
params['AssociationId'] = association_id
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('DisassociateAddress', params, verb='POST')
- def release_address(self, public_ip=None, allocation_id=None):
+ def release_address(self, public_ip=None, allocation_id=None,
+ dry_run=False):
"""
Free up an Elastic IP address. Pass a public IP address to
release an EC2 Elastic IP address and an AllocationId to
@@ -1623,6 +1833,9 @@ class EC2Connection(AWSQueryConnection):
:type allocation_id: string
:param allocation_id: The Allocation ID for VPC elastic IPs.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -1633,10 +1846,13 @@ class EC2Connection(AWSQueryConnection):
elif allocation_id is not None:
params['AllocationId'] = allocation_id
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('ReleaseAddress', params, verb='POST')
def unassign_private_ip_addresses(self, network_interface_id=None,
- private_ip_addresses=None):
+ private_ip_addresses=None, dry_run=False):
"""
Unassigns one or more secondary private IP addresses from a network
interface in Amazon VPC.
@@ -1649,6 +1865,9 @@ class EC2Connection(AWSQueryConnection):
:param private_ip_addresses: Specifies the secondary private IP
addresses that you want to unassign from the network interface.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -1661,12 +1880,15 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, private_ip_addresses,
'PrivateIpAddress')
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('UnassignPrivateIpAddresses', params,
verb='POST')
# Volume methods
- def get_all_volumes(self, volume_ids=None, filters=None):
+ def get_all_volumes(self, volume_ids=None, filters=None, dry_run=False):
"""
Get all Volumes associated with the current credentials.
@@ -1685,6 +1907,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.volume.Volume`
:return: The requested Volume objects
"""
@@ -1693,12 +1918,14 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, volume_ids, 'VolumeId')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeVolumes', params,
[('item', Volume)], verb='POST')
def get_all_volume_status(self, volume_ids=None,
max_results=None, next_token=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Retrieve the status of one or more volumes.
@@ -1723,6 +1950,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of volume status.
"""
@@ -1735,10 +1965,12 @@ class EC2Connection(AWSQueryConnection):
params['NextToken'] = next_token
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeVolumeStatus', params,
VolumeStatusSet, verb='POST')
- def enable_volume_io(self, volume_id):
+ def enable_volume_io(self, volume_id, dry_run=False):
"""
Enables I/O operations for a volume that had I/O operations
disabled because the data on the volume was potentially inconsistent.
@@ -1746,14 +1978,19 @@ class EC2Connection(AWSQueryConnection):
:type volume_id: str
:param volume_id: The ID of the volume.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'VolumeId': volume_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('EnableVolumeIO', params, verb='POST')
def get_volume_attribute(self, volume_id,
- attribute='autoEnableIO'):
+ attribute='autoEnableIO', dry_run=False):
"""
Describes attribute of the volume.
@@ -1765,14 +2002,20 @@ class EC2Connection(AWSQueryConnection):
* autoEnableIO
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.volume.VolumeAttribute`
:return: The requested Volume attribute
"""
params = {'VolumeId': volume_id, 'Attribute': attribute}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeVolumeAttribute', params,
VolumeAttribute, verb='POST')
- def modify_volume_attribute(self, volume_id, attribute, new_value):
+ def modify_volume_attribute(self, volume_id, attribute, new_value,
+ dry_run=False):
"""
Changes an attribute of an Volume.
@@ -1785,14 +2028,20 @@ class EC2Connection(AWSQueryConnection):
:type new_value: string
:param new_value: The new value of the attribute.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'VolumeId': volume_id}
if attribute == 'AutoEnableIO':
params['AutoEnableIO.Value'] = new_value
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ModifyVolumeAttribute', params, verb='POST')
def create_volume(self, size, zone, snapshot=None,
- volume_type=None, iops=None):
+ volume_type=None, iops=None, dry_run=False):
"""
Create a new EBS Volume.
@@ -1813,6 +2062,10 @@ class EC2Connection(AWSQueryConnection):
:type iops: int
:param iops: The provisioned IOPs you want to associate with
this volume. (optional)
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
if isinstance(zone, Zone):
zone = zone.name
@@ -1827,22 +2080,29 @@ class EC2Connection(AWSQueryConnection):
params['VolumeType'] = volume_type
if iops:
params['Iops'] = str(iops)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateVolume', params, Volume, verb='POST')
- def delete_volume(self, volume_id):
+ def delete_volume(self, volume_id, dry_run=False):
"""
Delete an EBS volume.
:type volume_id: str
:param volume_id: The ID of the volume to be delete.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'VolumeId': volume_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteVolume', params, verb='POST')
- def attach_volume(self, volume_id, instance_id, device):
+ def attach_volume(self, volume_id, instance_id, device, dry_run=False):
"""
Attach an EBS volume to an EC2 instance.
@@ -1857,16 +2117,21 @@ class EC2Connection(AWSQueryConnection):
:param device: The device on the instance through which the
volume will be exposted (e.g. /dev/sdh)
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'InstanceId': instance_id,
'VolumeId': volume_id,
'Device': device}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AttachVolume', params, verb='POST')
def detach_volume(self, volume_id, instance_id=None,
- device=None, force=False):
+ device=None, force=False, dry_run=False):
"""
Detach an EBS volume from an EC2 instance.
@@ -1891,6 +2156,9 @@ class EC2Connection(AWSQueryConnection):
use this option, you must perform file system check and
repair procedures.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -1901,13 +2169,15 @@ class EC2Connection(AWSQueryConnection):
params['Device'] = device
if force:
params['Force'] = 'true'
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DetachVolume', params, verb='POST')
# Snapshot methods
def get_all_snapshots(self, snapshot_ids=None,
owner=None, restorable_by=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Get all EBS Snapshots associated with the current credentials.
@@ -1938,6 +2208,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.snapshot.Snapshot`
:return: The requested Snapshot objects
"""
@@ -1950,10 +2223,12 @@ class EC2Connection(AWSQueryConnection):
params['RestorableBy'] = restorable_by
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeSnapshots', params,
[('item', Snapshot)], verb='POST')
- def create_snapshot(self, volume_id, description=None):
+ def create_snapshot(self, volume_id, description=None, dry_run=False):
"""
Create a snapshot of an existing EBS Volume.
@@ -1964,26 +2239,38 @@ class EC2Connection(AWSQueryConnection):
:param description: A description of the snapshot.
Limited to 255 characters.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.snapshot.Snapshot`
:return: The created Snapshot object
"""
params = {'VolumeId': volume_id}
if description:
params['Description'] = description[0:255]
+ if dry_run:
+ params['DryRun'] = 'true'
snapshot = self.get_object('CreateSnapshot', params,
Snapshot, verb='POST')
- volume = self.get_all_volumes([volume_id])[0]
+ volume = self.get_all_volumes([volume_id], dry_run=dry_run)[0]
volume_name = volume.tags.get('Name')
if volume_name:
snapshot.add_tag('Name', volume_name)
return snapshot
- def delete_snapshot(self, snapshot_id):
+ def delete_snapshot(self, snapshot_id, dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {'SnapshotId': snapshot_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteSnapshot', params, verb='POST')
def copy_snapshot(self, source_region, source_snapshot_id,
- description=None):
+ description=None, dry_run=False):
"""
Copies a point-in-time snapshot of an Amazon Elastic Block Store
(Amazon EBS) volume and stores it in Amazon Simple Storage Service
@@ -2002,6 +2289,9 @@ class EC2Connection(AWSQueryConnection):
:type description: str
:param description: A description of the new Amazon EBS snapshot.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: str
:return: The snapshot ID
@@ -2012,6 +2302,8 @@ class EC2Connection(AWSQueryConnection):
}
if description is not None:
params['Description'] = description
+ if dry_run:
+ params['DryRun'] = 'true'
snapshot = self.get_object('CopySnapshot', params, Snapshot,
verb='POST')
return snapshot.id
@@ -2170,7 +2462,8 @@ class EC2Connection(AWSQueryConnection):
snap_found_for_this_time_period = False
def get_snapshot_attribute(self, snapshot_id,
- attribute='createVolumePermission'):
+ attribute='createVolumePermission',
+ dry_run=False):
"""
Get information about an attribute of a snapshot. Only one attribute
can be specified per call.
@@ -2183,18 +2476,24 @@ class EC2Connection(AWSQueryConnection):
* createVolumePermission
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list of :class:`boto.ec2.snapshotattribute.SnapshotAttribute`
:return: The requested Snapshot attribute
"""
params = {'Attribute': attribute}
if snapshot_id:
params['SnapshotId'] = snapshot_id
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('DescribeSnapshotAttribute', params,
SnapshotAttribute, verb='POST')
def modify_snapshot_attribute(self, snapshot_id,
attribute='createVolumePermission',
- operation='add', user_ids=None, groups=None):
+ operation='add', user_ids=None, groups=None,
+ dry_run=False):
"""
Changes an attribute of an image.
@@ -2216,6 +2515,9 @@ class EC2Connection(AWSQueryConnection):
:param groups: The groups to add/remove attributes. The only valid
value at this time is 'all'.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'SnapshotId': snapshot_id,
'Attribute': attribute,
@@ -2224,10 +2526,13 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, user_ids, 'UserId')
if groups:
self.build_list_params(params, groups, 'UserGroup')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ModifySnapshotAttribute', params, verb='POST')
def reset_snapshot_attribute(self, snapshot_id,
- attribute='createVolumePermission'):
+ attribute='createVolumePermission',
+ dry_run=False):
"""
Resets an attribute of a snapshot to its default value.
@@ -2237,16 +2542,21 @@ class EC2Connection(AWSQueryConnection):
:type attribute: string
:param attribute: The attribute to reset
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: Whether the operation succeeded or not
"""
params = {'SnapshotId': snapshot_id,
'Attribute': attribute}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ResetSnapshotAttribute', params, verb='POST')
# Keypair methods
- def get_all_key_pairs(self, keynames=None, filters=None):
+ def get_all_key_pairs(self, keynames=None, filters=None, dry_run=False):
"""
Get all key pairs associated with your account.
@@ -2262,6 +2572,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.keypair.KeyPair`
"""
@@ -2270,28 +2583,36 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, keynames, 'KeyName')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeKeyPairs', params,
[('item', KeyPair)], verb='POST')
- def get_key_pair(self, keyname):
+ def get_key_pair(self, keyname, dry_run=False):
"""
Convenience method to retrieve a specific keypair (KeyPair).
:type keyname: string
:param keyname: The name of the keypair to retrieve
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.keypair.KeyPair`
:return: The KeyPair specified or None if it is not found
"""
try:
- return self.get_all_key_pairs(keynames=[keyname])[0]
+ return self.get_all_key_pairs(
+ keynames=[keyname],
+ dry_run=dry_run
+ )[0]
except self.ResponseError, e:
if e.code == 'InvalidKeyPair.NotFound':
return None
else:
raise
- def create_key_pair(self, key_name):
+ def create_key_pair(self, key_name, dry_run=False):
"""
Create a new key pair for your account.
This will create the key pair within the region you
@@ -2300,25 +2621,36 @@ class EC2Connection(AWSQueryConnection):
:type key_name: string
:param key_name: The name of the new keypair
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.keypair.KeyPair`
:return: The newly created :class:`boto.ec2.keypair.KeyPair`.
The material attribute of the new KeyPair object
will contain the the unencrypted PEM encoded RSA private key.
"""
params = {'KeyName': key_name}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateKeyPair', params, KeyPair, verb='POST')
- def delete_key_pair(self, key_name):
+ def delete_key_pair(self, key_name, dry_run=False):
"""
Delete a key pair from your account.
:type key_name: string
:param key_name: The name of the keypair to delete
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'KeyName': key_name}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteKeyPair', params, verb='POST')
- def import_key_pair(self, key_name, public_key_material):
+ def import_key_pair(self, key_name, public_key_material, dry_run=False):
"""
mports the public key from an RSA key pair that you created
with a third-party tool.
@@ -2345,6 +2677,9 @@ class EC2Connection(AWSQueryConnection):
the public key material before sending
it to AWS.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.keypair.KeyPair`
:return: A :class:`boto.ec2.keypair.KeyPair` object representing
the newly imported key pair. This object will contain only
@@ -2353,12 +2688,14 @@ class EC2Connection(AWSQueryConnection):
public_key_material = base64.b64encode(public_key_material)
params = {'KeyName': key_name,
'PublicKeyMaterial': public_key_material}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('ImportKeyPair', params, KeyPair, verb='POST')
# SecurityGroup methods
def get_all_security_groups(self, groupnames=None, group_ids=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Get all security groups associated with your account in a region.
@@ -2381,6 +2718,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.securitygroup.SecurityGroup`
"""
@@ -2391,11 +2731,13 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, group_ids, 'GroupId')
if filters is not None:
self.build_filter_params(params, filters)
-
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeSecurityGroups', params,
[('item', SecurityGroup)], verb='POST')
- def create_security_group(self, name, description, vpc_id=None):
+ def create_security_group(self, name, description, vpc_id=None,
+ dry_run=False):
"""
Create a new security group for your account.
This will create the security group within the region you
@@ -2411,6 +2753,9 @@ class EC2Connection(AWSQueryConnection):
:param vpc_id: The ID of the VPC to create the security group in,
if any.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
:return: The newly created :class:`boto.ec2.securitygroup.SecurityGroup`.
"""
@@ -2420,6 +2765,9 @@ class EC2Connection(AWSQueryConnection):
if vpc_id is not None:
params['VpcId'] = vpc_id
+ if dry_run:
+ params['DryRun'] = 'true'
+
group = self.get_object('CreateSecurityGroup', params,
SecurityGroup, verb='POST')
group.name = name
@@ -2428,7 +2776,7 @@ class EC2Connection(AWSQueryConnection):
group.vpc_id = vpc_id
return group
- def delete_security_group(self, name=None, group_id=None):
+ def delete_security_group(self, name=None, group_id=None, dry_run=False):
"""
Delete a security group from your account.
@@ -2439,6 +2787,9 @@ class EC2Connection(AWSQueryConnection):
:param group_id: The ID of the security group to delete within
a VPC.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2449,6 +2800,9 @@ class EC2Connection(AWSQueryConnection):
elif group_id is not None:
params['GroupId'] = group_id
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_status('DeleteSecurityGroup', params, verb='POST')
def authorize_security_group_deprecated(self, group_name,
@@ -2456,7 +2810,7 @@ class EC2Connection(AWSQueryConnection):
src_security_group_owner_id=None,
ip_protocol=None,
from_port=None, to_port=None,
- cidr_ip=None):
+ cidr_ip=None, dry_run=False):
"""
NOTE: This method uses the old-style request parameters
that did not allow a port to be specified when
@@ -2487,6 +2841,9 @@ class EC2Connection(AWSQueryConnection):
:param to_port: The CIDR block you are providing access to.
See http://goo.gl/Yj5QC
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2503,6 +2860,8 @@ class EC2Connection(AWSQueryConnection):
params['ToPort'] = to_port
if cidr_ip:
params['CidrIp'] = cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AuthorizeSecurityGroupIngress', params)
def authorize_security_group(self, group_name=None,
@@ -2511,7 +2870,8 @@ class EC2Connection(AWSQueryConnection):
ip_protocol=None,
from_port=None, to_port=None,
cidr_ip=None, group_id=None,
- src_security_group_group_id=None):
+ src_security_group_group_id=None,
+ dry_run=False):
"""
Add a new rule to an existing security group.
You need to pass in either src_security_group_name and
@@ -2554,6 +2914,9 @@ class EC2Connection(AWSQueryConnection):
group you are granting access to. Can be used instead of
src_security_group_name
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2590,6 +2953,8 @@ class EC2Connection(AWSQueryConnection):
for i, single_cidr_ip in enumerate(cidr_ip):
params['IpPermissions.1.IpRanges.%d.CidrIp' % (i+1)] = \
single_cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AuthorizeSecurityGroupIngress',
params, verb='POST')
@@ -2600,13 +2965,18 @@ class EC2Connection(AWSQueryConnection):
from_port=None,
to_port=None,
src_group_id=None,
- cidr_ip=None):
+ cidr_ip=None,
+ dry_run=False):
"""
The action adds one or more egress rules to a VPC security
group. Specifically, this action permits instances in a
security group to send traffic to one or more destination
CIDR IP address ranges, or to one or more destination
security groups in the same VPC.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {
'GroupId': group_id,
@@ -2621,6 +2991,8 @@ class EC2Connection(AWSQueryConnection):
params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
if cidr_ip is not None:
params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AuthorizeSecurityGroupEgress',
params, verb='POST')
@@ -2630,7 +3002,7 @@ class EC2Connection(AWSQueryConnection):
src_security_group_owner_id=None,
ip_protocol=None,
from_port=None, to_port=None,
- cidr_ip=None):
+ cidr_ip=None, dry_run=False):
"""
NOTE: This method uses the old-style request parameters
that did not allow a port to be specified when
@@ -2667,6 +3039,9 @@ class EC2Connection(AWSQueryConnection):
:param to_port: The CIDR block you are revoking access to.
http://goo.gl/Yj5QC
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2683,6 +3058,8 @@ class EC2Connection(AWSQueryConnection):
params['ToPort'] = to_port
if cidr_ip:
params['CidrIp'] = cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('RevokeSecurityGroupIngress', params)
def revoke_security_group(self, group_name=None,
@@ -2690,7 +3067,7 @@ class EC2Connection(AWSQueryConnection):
src_security_group_owner_id=None,
ip_protocol=None, from_port=None, to_port=None,
cidr_ip=None, group_id=None,
- src_security_group_group_id=None):
+ src_security_group_group_id=None, dry_run=False):
"""
Remove an existing rule from an existing security group.
You need to pass in either src_security_group_name and
@@ -2733,6 +3110,9 @@ class EC2Connection(AWSQueryConnection):
for which you are revoking access. Can be used instead
of src_security_group_name
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2763,6 +3143,8 @@ class EC2Connection(AWSQueryConnection):
params['IpPermissions.1.ToPort'] = to_port
if cidr_ip:
params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('RevokeSecurityGroupIngress',
params, verb='POST')
@@ -2772,7 +3154,7 @@ class EC2Connection(AWSQueryConnection):
from_port=None,
to_port=None,
src_group_id=None,
- cidr_ip=None):
+ cidr_ip=None, dry_run=False):
"""
Remove an existing egress rule from an existing VPC security
group. You need to pass in an ip_protocol, from_port and
@@ -2801,6 +3183,9 @@ class EC2Connection(AWSQueryConnection):
:param cidr_ip: The CIDR block you are revoking access to.
See http://goo.gl/Yj5QC
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful.
"""
@@ -2818,6 +3203,8 @@ class EC2Connection(AWSQueryConnection):
params['IpPermissions.1.Groups.1.GroupId'] = src_group_id
if cidr_ip:
params['IpPermissions.1.IpRanges.1.CidrIp'] = cidr_ip
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('RevokeSecurityGroupEgress',
params, verb='POST')
@@ -2825,7 +3212,7 @@ class EC2Connection(AWSQueryConnection):
# Regions
#
- def get_all_regions(self, region_names=None, filters=None):
+ def get_all_regions(self, region_names=None, filters=None, dry_run=False):
"""
Get all available regions for the EC2 service.
@@ -2842,6 +3229,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.regioninfo.RegionInfo`
"""
@@ -2850,6 +3240,8 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, region_names, 'RegionName')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
regions = self.get_list('DescribeRegions', params,
[('item', RegionInfo)], verb='POST')
for region in regions:
@@ -2873,7 +3265,8 @@ class EC2Connection(AWSQueryConnection):
max_duration=None,
max_instance_count=None,
next_token=None,
- max_results=None):
+ max_results=None,
+ dry_run=False):
"""
Describes Reserved Instance offerings that are available for purchase.
@@ -2935,6 +3328,9 @@ class EC2Connection(AWSQueryConnection):
:type max_results: int
:param max_results: Maximum number of offerings to return per call.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of
:class:`boto.ec2.reservedinstance.ReservedInstancesOffering`.
@@ -2971,13 +3367,15 @@ class EC2Connection(AWSQueryConnection):
params['NextToken'] = next_token
if max_results is not None:
params['MaxResults'] = str(max_results)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeReservedInstancesOfferings',
params, [('item', ReservedInstancesOffering)],
verb='POST')
def get_all_reserved_instances(self, reserved_instances_id=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Describes one or more of the Reserved Instances that you purchased.
@@ -2994,6 +3392,9 @@ class EC2Connection(AWSQueryConnection):
names/values is dependent on the request being performed.
Check the EC2 API guide for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.reservedinstance.ReservedInstance`
"""
@@ -3003,12 +3404,15 @@ class EC2Connection(AWSQueryConnection):
'ReservedInstancesId')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeReservedInstances',
params, [('item', ReservedInstance)], verb='POST')
def purchase_reserved_instance_offering(self,
reserved_instances_offering_id,
- instance_count=1, limit_price=None):
+ instance_count=1, limit_price=None,
+ dry_run=False):
"""
Purchase a Reserved Instance for use with your account.
** CAUTION **
@@ -3028,6 +3432,9 @@ class EC2Connection(AWSQueryConnection):
Must be a tuple of (amount, currency_code), for example:
(100.0, 'USD').
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.reservedinstance.ReservedInstance`
:return: The newly created Reserved Instance
"""
@@ -3037,11 +3444,14 @@ class EC2Connection(AWSQueryConnection):
if limit_price is not None:
params['LimitPrice.Amount'] = str(limit_price[0])
params['LimitPrice.CurrencyCode'] = str(limit_price[1])
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('PurchaseReservedInstancesOffering', params,
ReservedInstance, verb='POST')
- def create_reserved_instances_listing(self, reserved_instances_id, instance_count,
- price_schedules, client_token):
+ def create_reserved_instances_listing(self, reserved_instances_id,
+ instance_count, price_schedules,
+ client_token, dry_run=False):
"""Creates a new listing for Reserved Instances.
Creates a new listing for Amazon EC2 Reserved Instances that will be
@@ -3087,6 +3497,9 @@ class EC2Connection(AWSQueryConnection):
:param client_token: Unique, case-sensitive identifier you provide
to ensure idempotency of the request. Maximum 64 ASCII characters.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of
:class:`boto.ec2.reservedinstance.ReservedInstanceListing`
@@ -3101,17 +3514,23 @@ class EC2Connection(AWSQueryConnection):
price, term = schedule
params['PriceSchedules.%s.Price' % i] = str(price)
params['PriceSchedules.%s.Term' % i] = str(term)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('CreateReservedInstancesListing',
params, [('item', ReservedInstanceListing)], verb='POST')
- def cancel_reserved_instances_listing(
- self, reserved_instances_listing_ids=None):
+ def cancel_reserved_instances_listing(self,
+ reserved_instances_listing_ids=None,
+ dry_run=False):
"""Cancels the specified Reserved Instance listing.
:type reserved_instances_listing_ids: List of strings
:param reserved_instances_listing_ids: The ID of the
Reserved Instance listing to be cancelled.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of
:class:`boto.ec2.reservedinstance.ReservedInstanceListing`
@@ -3121,6 +3540,8 @@ class EC2Connection(AWSQueryConnection):
if reserved_instances_listing_ids is not None:
self.build_list_params(params, reserved_instances_listing_ids,
'ReservedInstancesListingId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('CancelReservedInstancesListing',
params, [('item', ReservedInstanceListing)], verb='POST')
@@ -3128,22 +3549,27 @@ class EC2Connection(AWSQueryConnection):
# Monitoring
#
- def monitor_instances(self, instance_ids):
+ def monitor_instances(self, instance_ids, dry_run=False):
"""
Enable CloudWatch monitoring for the supplied instances.
:type instance_id: list of strings
:param instance_id: The instance ids
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
"""
params = {}
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('MonitorInstances', params,
[('item', InstanceInfo)], verb='POST')
- def monitor_instance(self, instance_id):
+ def monitor_instance(self, instance_id, dry_run=False):
"""
Deprecated Version, maintained for backward compatibility.
Enable CloudWatch monitoring for the supplied instance.
@@ -3151,27 +3577,35 @@ class EC2Connection(AWSQueryConnection):
:type instance_id: string
:param instance_id: The instance id
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
"""
- return self.monitor_instances([instance_id])
+ return self.monitor_instances([instance_id], dry_run=dry_run)
- def unmonitor_instances(self, instance_ids):
+ def unmonitor_instances(self, instance_ids, dry_run=False):
"""
Disable CloudWatch monitoring for the supplied instance.
:type instance_id: list of string
:param instance_id: The instance id
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
"""
params = {}
self.build_list_params(params, instance_ids, 'InstanceId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('UnmonitorInstances', params,
[('item', InstanceInfo)], verb='POST')
- def unmonitor_instance(self, instance_id):
+ def unmonitor_instance(self, instance_id, dry_run=False):
"""
Deprecated Version, maintained for backward compatibility.
Disable CloudWatch monitoring for the supplied instance.
@@ -3179,10 +3613,13 @@ class EC2Connection(AWSQueryConnection):
:type instance_id: string
:param instance_id: The instance id
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.instanceinfo.InstanceInfo`
"""
- return self.unmonitor_instances([instance_id])
+ return self.unmonitor_instances([instance_id], dry_run=dry_run)
#
# Bundle Windows Instances
@@ -3191,7 +3628,7 @@ class EC2Connection(AWSQueryConnection):
def bundle_instance(self, instance_id,
s3_bucket,
s3_prefix,
- s3_upload_policy):
+ s3_upload_policy, dry_run=False):
"""
Bundle Windows instance.
@@ -3208,6 +3645,10 @@ class EC2Connection(AWSQueryConnection):
:param s3_upload_policy: Base64 encoded policy that specifies condition
and permissions for Amazon EC2 to upload the
user's image into Amazon S3.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'InstanceId': instance_id,
@@ -3219,10 +3660,13 @@ class EC2Connection(AWSQueryConnection):
params['Storage.S3.AWSAccessKeyId'] = self.aws_access_key_id
signature = s3auth.sign_string(s3_upload_policy)
params['Storage.S3.UploadPolicySignature'] = signature
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('BundleInstance', params,
BundleInstanceTask, verb='POST')
- def get_all_bundle_tasks(self, bundle_ids=None, filters=None):
+ def get_all_bundle_tasks(self, bundle_ids=None, filters=None,
+ dry_run=False):
"""
Retrieve current bundling tasks. If no bundle id is specified, all
tasks are retrieved.
@@ -3241,38 +3685,52 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
- """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+ """
params = {}
if bundle_ids:
self.build_list_params(params, bundle_ids, 'BundleId')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeBundleTasks', params,
[('item', BundleInstanceTask)], verb='POST')
- def cancel_bundle_task(self, bundle_id):
+ def cancel_bundle_task(self, bundle_id, dry_run=False):
"""
Cancel a previously submitted bundle task
:type bundle_id: string
:param bundle_id: The identifier of the bundle task to cancel.
- """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {'BundleId': bundle_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CancelBundleTask', params,
BundleInstanceTask, verb='POST')
- def get_password_data(self, instance_id):
+ def get_password_data(self, instance_id, dry_run=False):
"""
Get encrypted administrator password for a Windows instance.
:type instance_id: string
:param instance_id: The identifier of the instance to retrieve the
password for.
- """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {'InstanceId': instance_id}
+ if dry_run:
+ params['DryRun'] = 'true'
rs = self.get_object('GetPasswordData', params, ResultSet, verb='POST')
return rs.passwordData
@@ -3280,7 +3738,8 @@ class EC2Connection(AWSQueryConnection):
# Cluster Placement Groups
#
- def get_all_placement_groups(self, groupnames=None, filters=None):
+ def get_all_placement_groups(self, groupnames=None, filters=None,
+ dry_run=False):
"""
Get all placement groups associated with your account in a region.
@@ -3299,6 +3758,9 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.placementgroup.PlacementGroup`
"""
@@ -3307,10 +3769,12 @@ class EC2Connection(AWSQueryConnection):
self.build_list_params(params, groupnames, 'GroupName')
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribePlacementGroups', params,
[('item', PlacementGroup)], verb='POST')
- def create_placement_group(self, name, strategy='cluster'):
+ def create_placement_group(self, name, strategy='cluster', dry_run=False):
"""
Create a new placement group for your account.
This will create the placement group within the region you
@@ -3323,21 +3787,32 @@ class EC2Connection(AWSQueryConnection):
:param strategy: The placement strategy of the new placement group.
Currently, the only acceptable value is "cluster".
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'GroupName':name, 'Strategy':strategy}
+ if dry_run:
+ params['DryRun'] = 'true'
group = self.get_status('CreatePlacementGroup', params, verb='POST')
return group
- def delete_placement_group(self, name):
+ def delete_placement_group(self, name, dry_run=False):
"""
Delete a placement group from your account.
:type key_name: string
:param key_name: The name of the keypair to delete
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'GroupName':name}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeletePlacementGroup', params, verb='POST')
# Tag methods
@@ -3352,7 +3827,7 @@ class EC2Connection(AWSQueryConnection):
params['Tag.%d.Value'%i] = value
i += 1
- def get_all_tags(self, filters=None):
+ def get_all_tags(self, filters=None, dry_run=False):
"""
Retrieve all the metadata tags associated with your account.
@@ -3366,16 +3841,21 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.tag.Tag` objects
"""
params = {}
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeTags', params,
[('item', Tag)], verb='POST')
- def create_tags(self, resource_ids, tags):
+ def create_tags(self, resource_ids, tags, dry_run=False):
"""
Create new metadata tags for the specified resource ids.
@@ -3388,13 +3868,18 @@ class EC2Connection(AWSQueryConnection):
value for that tag should be the empty string
(e.g. '').
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {}
self.build_list_params(params, resource_ids, 'ResourceId')
self.build_tag_param_list(params, tags)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('CreateTags', params, verb='POST')
- def delete_tags(self, resource_ids, tags):
+ def delete_tags(self, resource_ids, tags, dry_run=False):
"""
Delete metadata tags for the specified resource ids.
@@ -3410,17 +3895,22 @@ class EC2Connection(AWSQueryConnection):
for the tag value, all tags with that name will
be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
if isinstance(tags, list):
tags = {}.fromkeys(tags, None)
params = {}
self.build_list_params(params, resource_ids, 'ResourceId')
self.build_tag_param_list(params, tags)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteTags', params, verb='POST')
# Network Interface methods
- def get_all_network_interfaces(self, filters=None):
+ def get_all_network_interfaces(self, filters=None, dry_run=False):
"""
Retrieve all of the Elastic Network Interfaces (ENI's)
associated with your account.
@@ -3435,17 +3925,22 @@ class EC2Connection(AWSQueryConnection):
being performed. Check the EC2 API guide
for details.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.ec2.networkinterface.NetworkInterface`
"""
params = {}
if filters:
self.build_filter_params(params, filters)
+ if dry_run:
+ params['DryRun'] = 'true'
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):
+ description=None, groups=None, dry_run=False):
"""
Creates a network interface in the specified subnet.
@@ -3466,6 +3961,9 @@ class EC2Connection(AWSQueryConnection):
This can be either a list of group ID's or a list of
:class:`boto.ec2.securitygroup.SecurityGroup` objects.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: :class:`boto.ec2.networkinterface.NetworkInterface`
:return: The newly created network interface.
"""
@@ -3482,11 +3980,13 @@ class EC2Connection(AWSQueryConnection):
else:
ids.append(group)
self.build_list_params(params, ids, 'SecurityGroupId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateNetworkInterface', params,
NetworkInterface, verb='POST')
def attach_network_interface(self, network_interface_id,
- instance_id, device_index):
+ instance_id, device_index, dry_run=False):
"""
Attaches a network interface to an instance.
@@ -3500,13 +4000,20 @@ class EC2Connection(AWSQueryConnection):
:type device_index: int
:param device_index: The index of the device for the network
interface attachment on the instance.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'NetworkInterfaceId': network_interface_id,
'InstanceId': instance_id,
'DeviceIndex': device_index}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AttachNetworkInterface', params, verb='POST')
- def detach_network_interface(self, attachment_id, force=False):
+ def detach_network_interface(self, attachment_id, force=False,
+ dry_run=False):
"""
Detaches a network interface from an instance.
@@ -3516,21 +4023,31 @@ class EC2Connection(AWSQueryConnection):
:type force: bool
:param force: Set to true to force a detachment.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'AttachmentId': attachment_id}
if force:
params['Force'] = 'true'
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DetachNetworkInterface', params, verb='POST')
- def delete_network_interface(self, network_interface_id):
+ def delete_network_interface(self, network_interface_id, dry_run=False):
"""
Delete the specified network interface.
:type network_interface_id: str
:param network_interface_id: The ID of the network interface to delete.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'NetworkInterfaceId': network_interface_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteNetworkInterface', params, verb='POST')
def get_all_vmtypes(self):
@@ -3544,7 +4061,12 @@ class EC2Connection(AWSQueryConnection):
return self.get_list('DescribeVmTypes', params, [('euca:item', VmType)], verb='POST')
def copy_image(self, source_region, source_image_id, name,
- description=None, client_token=None):
+ description=None, client_token=None, dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {
'SourceRegion': source_region,
'SourceImageId': source_image_id,
@@ -3554,29 +4076,48 @@ class EC2Connection(AWSQueryConnection):
params['Description'] = description
if client_token is not None:
params['ClientToken'] = client_token
- image = self.get_object('CopyImage', params, CopyImage,
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_object('CopyImage', params, CopyImage,
verb='POST')
- return image
- def describe_account_attributes(self, attribute_names=None):
+ def describe_account_attributes(self, attribute_names=None, dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {}
if attribute_names is not None:
self.build_list_params(params, attribute_names, 'AttributeName')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeAccountAttributes', params,
[('item', AccountAttribute)], verb='POST')
- def describe_vpc_attribute(self, vpc_id, attribute=None):
+ def describe_vpc_attribute(self, vpc_id, attribute=None, dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {
'VpcId': vpc_id
}
if attribute is not None:
params['Attribute'] = attribute
- attr = self.get_object('DescribeVpcAttribute', params,
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_object('DescribeVpcAttribute', params,
VPCAttribute, verb='POST')
- return attr
def modify_vpc_attribute(self, vpc_id, enable_dns_support=None,
- enable_dns_hostnames=None):
+ enable_dns_hostnames=None, dry_run=False):
+ """
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
+ """
params = {
'VpcId': vpc_id
}
@@ -3586,5 +4127,6 @@ class EC2Connection(AWSQueryConnection):
if enable_dns_hostnames is not None:
params['EnableDnsHostnames.Value'] = (
'true' if enable_dns_hostnames else 'false')
- result = self.get_status('ModifyVpcAttribute', params, verb='POST')
- return result
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_status('ModifyVpcAttribute', params, verb='POST')
diff --git a/boto/ec2/ec2object.py b/boto/ec2/ec2object.py
index 7756bee7..265678c6 100644
--- a/boto/ec2/ec2object.py
+++ b/boto/ec2/ec2object.py
@@ -15,7 +15,7 @@
# 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,
+# 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.
@@ -40,7 +40,7 @@ class EC2Object(object):
def endElement(self, name, value, connection):
setattr(self, name, value)
-
+
class TaggedEC2Object(EC2Object):
"""
Any EC2 resource that can be tagged should be represented
@@ -62,7 +62,7 @@ class TaggedEC2Object(EC2Object):
else:
return None
- def add_tag(self, key, value=''):
+ def add_tag(self, key, value='', dry_run=False):
"""
Add a tag to this object. Tag's are stored by AWS and can be used
to organize and filter resources. Adding a tag involves a round-trip
@@ -76,12 +76,16 @@ class TaggedEC2Object(EC2Object):
If you want only the tag name and no value, the
value should be the empty string.
"""
- status = self.connection.create_tags([self.id], {key : value})
+ status = self.connection.create_tags(
+ [self.id],
+ {key : value},
+ dry_run=dry_run
+ )
if self.tags is None:
self.tags = TagSet()
self.tags[key] = value
- def remove_tag(self, key, value=None):
+ def remove_tag(self, key, value=None, dry_run=False):
"""
Remove a tag from this object. Removing a tag involves a round-trip
to the EC2 service.
@@ -102,6 +106,10 @@ class TaggedEC2Object(EC2Object):
tags = {key : value}
else:
tags = [key]
- status = self.connection.delete_tags([self.id], tags)
+ status = self.connection.delete_tags(
+ [self.id],
+ tags,
+ dry_run=dry_run
+ )
if key in self.tags:
del self.tags[key]
diff --git a/boto/ec2/image.py b/boto/ec2/image.py
index 376fc869..6b6d9ce9 100644
--- a/boto/ec2/image.py
+++ b/boto/ec2/image.py
@@ -130,7 +130,7 @@ class Image(TaggedEC2Object):
def _update(self, updated):
self.__dict__.update(updated.__dict__)
- def update(self, validate=False):
+ def update(self, validate=False, dry_run=False):
"""
Update the image's state information by making a call to fetch
the current image attributes from the service.
@@ -142,7 +142,7 @@ class Image(TaggedEC2Object):
raise a ValueError exception if no data is
returned from EC2.
"""
- rs = self.connection.get_all_images([self.id])
+ rs = self.connection.get_all_images([self.id], dry_run=dry_run)
if len(rs) > 0:
img = rs[0]
if img.id == self.id:
@@ -162,7 +162,7 @@ class Image(TaggedEC2Object):
private_ip_address=None,
placement_group=None, security_group_ids=None,
additional_info=None, instance_profile_name=None,
- instance_profile_arn=None, tenancy=None):
+ instance_profile_arn=None, tenancy=None, dry_run=False):
"""
Runs this instance.
@@ -295,40 +295,62 @@ class Image(TaggedEC2Object):
additional_info=additional_info,
instance_profile_name=instance_profile_name,
instance_profile_arn=instance_profile_arn,
- tenancy=tenancy)
-
- def deregister(self, delete_snapshot=False):
- return self.connection.deregister_image(self.id, delete_snapshot)
-
- def get_launch_permissions(self):
- img_attrs = self.connection.get_image_attribute(self.id,
- 'launchPermission')
+ tenancy=tenancy, dry_run=dry_run)
+
+ def deregister(self, delete_snapshot=False, dry_run=False):
+ return self.connection.deregister_image(
+ self.id,
+ delete_snapshot,
+ dry_run=dry_run
+ )
+
+ def get_launch_permissions(self, dry_run=False):
+ img_attrs = self.connection.get_image_attribute(
+ self.id,
+ 'launchPermission',
+ dry_run=dry_run
+ )
return img_attrs.attrs
- def set_launch_permissions(self, user_ids=None, group_names=None):
+ def set_launch_permissions(self, user_ids=None, group_names=None,
+ dry_run=False):
return self.connection.modify_image_attribute(self.id,
'launchPermission',
'add',
user_ids,
- group_names)
+ group_names,
+ dry_run=dry_run)
- def remove_launch_permissions(self, user_ids=None, group_names=None):
+ def remove_launch_permissions(self, user_ids=None, group_names=None,
+ dry_run=False):
return self.connection.modify_image_attribute(self.id,
'launchPermission',
'remove',
user_ids,
- group_names)
-
- def reset_launch_attributes(self):
- return self.connection.reset_image_attribute(self.id,
- 'launchPermission')
-
- def get_kernel(self):
- img_attrs =self.connection.get_image_attribute(self.id, 'kernel')
+ group_names,
+ dry_run=dry_run)
+
+ def reset_launch_attributes(self, dry_run=False):
+ return self.connection.reset_image_attribute(
+ self.id,
+ 'launchPermission',
+ dry_run=dry_run
+ )
+
+ def get_kernel(self, dry_run=False):
+ img_attrs =self.connection.get_image_attribute(
+ self.id,
+ 'kernel',
+ dry_run=dry_run
+ )
return img_attrs.kernel
- def get_ramdisk(self):
- img_attrs = self.connection.get_image_attribute(self.id, 'ramdisk')
+ def get_ramdisk(self, dry_run=False):
+ img_attrs = self.connection.get_image_attribute(
+ self.id,
+ 'ramdisk',
+ dry_run=dry_run
+ )
return img_attrs.ramdisk
class ImageAttribute:
diff --git a/boto/ec2/instance.py b/boto/ec2/instance.py
index e0137705..254fe230 100644
--- a/boto/ec2/instance.py
+++ b/boto/ec2/instance.py
@@ -149,9 +149,9 @@ class Reservation(EC2Object):
else:
setattr(self, name, value)
- def stop_all(self):
+ def stop_all(self, dry_run=False):
for instance in self.instances:
- instance.stop()
+ instance.stop(dry_run=dry_run)
class Instance(TaggedEC2Object):
@@ -406,7 +406,7 @@ class Instance(TaggedEC2Object):
def _update(self, updated):
self.__dict__.update(updated.__dict__)
- def update(self, validate=False):
+ def update(self, validate=False, dry_run=False):
"""
Update the instance's state information by making a call to fetch
the current instance attributes from the service.
@@ -418,7 +418,7 @@ class Instance(TaggedEC2Object):
raise a ValueError exception if no data is
returned from EC2.
"""
- rs = self.connection.get_all_reservations([self.id])
+ rs = self.connection.get_all_reservations([self.id], dry_run=dry_run)
if len(rs) > 0:
r = rs[0]
for i in r.instances:
@@ -428,15 +428,15 @@ class Instance(TaggedEC2Object):
raise ValueError('%s is not a valid Instance ID' % self.id)
return self.state
- def terminate(self):
+ def terminate(self, dry_run=False):
"""
Terminate the instance
"""
- rs = self.connection.terminate_instances([self.id])
+ rs = self.connection.terminate_instances([self.id], dry_run=dry_run)
if len(rs) > 0:
self._update(rs[0])
- def stop(self, force=False):
+ def stop(self, force=False, dry_run=False):
"""
Stop the instance
@@ -446,34 +446,38 @@ class Instance(TaggedEC2Object):
:rtype: list
:return: A list of the instances stopped
"""
- rs = self.connection.stop_instances([self.id], force)
+ rs = self.connection.stop_instances([self.id], force, dry_run=dry_run)
if len(rs) > 0:
self._update(rs[0])
- def start(self):
+ def start(self, dry_run=False):
"""
Start the instance.
"""
- rs = self.connection.start_instances([self.id])
+ rs = self.connection.start_instances([self.id], dry_run=dry_run)
if len(rs) > 0:
self._update(rs[0])
- def reboot(self):
- return self.connection.reboot_instances([self.id])
+ def reboot(self, dry_run=False):
+ return self.connection.reboot_instances([self.id], dry_run=dry_run)
- def get_console_output(self):
+ def get_console_output(self, dry_run=False):
"""
Retrieves the console output for the instance.
:rtype: :class:`boto.ec2.instance.ConsoleOutput`
:return: The console output as a ConsoleOutput object
"""
- return self.connection.get_console_output(self.id)
+ return self.connection.get_console_output(self.id, dry_run=dry_run)
- def confirm_product(self, product_code):
- return self.connection.confirm_product_instance(self.id, product_code)
+ def confirm_product(self, product_code, dry_run=False):
+ return self.connection.confirm_product_instance(
+ self.id,
+ product_code,
+ dry_run=dry_run
+ )
- def use_ip(self, ip_address):
+ def use_ip(self, ip_address, dry_run=False):
"""
Associates an Elastic IP to the instance.
@@ -488,15 +492,19 @@ class Instance(TaggedEC2Object):
if isinstance(ip_address, Address):
ip_address = ip_address.public_ip
- return self.connection.associate_address(self.id, ip_address)
+ return self.connection.associate_address(
+ self.id,
+ ip_address,
+ dry_run=dry_run
+ )
- def monitor(self):
- return self.connection.monitor_instance(self.id)
+ def monitor(self, dry_run=False):
+ return self.connection.monitor_instance(self.id, dry_run=dry_run)
- def unmonitor(self):
- return self.connection.unmonitor_instance(self.id)
+ def unmonitor(self, dry_run=False):
+ return self.connection.unmonitor_instance(self.id, dry_run=dry_run)
- def get_attribute(self, attribute):
+ def get_attribute(self, attribute, dry_run=False):
"""
Gets an attribute from this instance.
@@ -521,9 +529,13 @@ class Instance(TaggedEC2Object):
:return: An InstanceAttribute object representing the value of the
attribute requested
"""
- return self.connection.get_instance_attribute(self.id, attribute)
+ return self.connection.get_instance_attribute(
+ self.id,
+ attribute,
+ dry_run=dry_run
+ )
- def modify_attribute(self, attribute, value):
+ def modify_attribute(self, attribute, value, dry_run=False):
"""
Changes an attribute of this instance
@@ -546,10 +558,14 @@ class Instance(TaggedEC2Object):
:rtype: bool
:return: Whether the operation succeeded or not
"""
- return self.connection.modify_instance_attribute(self.id, attribute,
- value)
-
- def reset_attribute(self, attribute):
+ return self.connection.modify_instance_attribute(
+ self.id,
+ attribute,
+ value,
+ dry_run=dry_run
+ )
+
+ def reset_attribute(self, attribute, dry_run=False):
"""
Resets an attribute of this instance to its default value.
@@ -560,12 +576,14 @@ class Instance(TaggedEC2Object):
:rtype: bool
:return: Whether the operation succeeded or not
"""
- return self.connection.reset_instance_attribute(self.id, attribute)
-
- def create_image(
- self, name,
- description=None, no_reboot=False
- ):
+ return self.connection.reset_instance_attribute(
+ self.id,
+ attribute,
+ dry_run=dry_run
+ )
+
+ def create_image(self, name, description=None, no_reboot=False,
+ dry_run=False):
"""
Will create an AMI from the instance in the running or stopped
state.
@@ -587,7 +605,13 @@ class Instance(TaggedEC2Object):
:rtype: string
:return: The new image id
"""
- return self.connection.create_image(self.id, name, description, no_reboot)
+ return self.connection.create_image(
+ self.id,
+ name,
+ description,
+ no_reboot,
+ dry_run=dry_run
+ )
class ConsoleOutput:
diff --git a/boto/ec2/keypair.py b/boto/ec2/keypair.py
index 65c95908..c15a0984 100644
--- a/boto/ec2/keypair.py
+++ b/boto/ec2/keypair.py
@@ -14,7 +14,7 @@
# 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,
+# 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.
@@ -28,7 +28,7 @@ from boto.ec2.ec2object import EC2Object
from boto.exception import BotoClientError
class KeyPair(EC2Object):
-
+
def __init__(self, connection=None):
EC2Object.__init__(self, connection)
self.name = None
@@ -48,20 +48,20 @@ class KeyPair(EC2Object):
else:
setattr(self, name, value)
- def delete(self):
+ def delete(self, dry_run=False):
"""
Delete the KeyPair.
-
+
:rtype: bool
:return: True if successful, otherwise False.
"""
- return self.connection.delete_key_pair(self.name)
+ return self.connection.delete_key_pair(self.name, dry_run=dry_run)
def save(self, directory_path):
"""
Save the material (the unencrypted PEM encoded RSA private key)
of a newly created KeyPair to a local file.
-
+
:type directory_path: string
:param directory_path: The fully qualified path to the directory
in which the keypair will be saved. The
@@ -71,7 +71,7 @@ class KeyPair(EC2Object):
name already exists in the directory, an
exception will be raised and the old file
will not be overwritten.
-
+
:rtype: bool
:return: True if successful.
"""
@@ -88,7 +88,7 @@ class KeyPair(EC2Object):
else:
raise BotoClientError('KeyPair contains no material')
- def copy_to_region(self, region):
+ def copy_to_region(self, region, dry_run=False):
"""
Create a new key pair of the same new in another region.
Note that the new key pair will use a different ssh
@@ -106,7 +106,7 @@ class KeyPair(EC2Object):
raise BotoClientError('Unable to copy to the same Region')
conn_params = self.connection.get_params()
rconn = region.connect(**conn_params)
- kp = rconn.create_key_pair(self.name)
+ kp = rconn.create_key_pair(self.name, dry_run=dry_run)
return kp
diff --git a/boto/ec2/networkinterface.py b/boto/ec2/networkinterface.py
index 6ae7fe60..98368050 100644
--- a/boto/ec2/networkinterface.py
+++ b/boto/ec2/networkinterface.py
@@ -166,8 +166,11 @@ class NetworkInterface(TaggedEC2Object):
else:
setattr(self, name, value)
- def delete(self):
- return self.connection.delete_network_interface(self.id)
+ def delete(self, dry_run=False):
+ return self.connection.delete_network_interface(
+ self.id,
+ dry_run=dry_run
+ )
class PrivateIPAddress(object):
diff --git a/boto/ec2/placementgroup.py b/boto/ec2/placementgroup.py
index e1bbea62..79bd4c46 100644
--- a/boto/ec2/placementgroup.py
+++ b/boto/ec2/placementgroup.py
@@ -14,7 +14,7 @@
# 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,
+# 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.
@@ -25,7 +25,7 @@ from boto.ec2.ec2object import EC2Object
from boto.exception import BotoClientError
class PlacementGroup(EC2Object):
-
+
def __init__(self, connection=None, name=None, strategy=None, state=None):
EC2Object.__init__(self, connection)
self.name = name
@@ -45,7 +45,10 @@ class PlacementGroup(EC2Object):
else:
setattr(self, name, value)
- def delete(self):
- return self.connection.delete_placement_group(self.name)
+ def delete(self, dry_run=False):
+ return self.connection.delete_placement_group(
+ self.name,
+ dry_run=dry_run
+ )
diff --git a/boto/ec2/reservedinstance.py b/boto/ec2/reservedinstance.py
index d92f1686..725ff2d2 100644
--- a/boto/ec2/reservedinstance.py
+++ b/boto/ec2/reservedinstance.py
@@ -89,8 +89,12 @@ class ReservedInstancesOffering(EC2Object):
print '\tUsage Price=%s' % self.usage_price
print '\tDescription=%s' % self.description
- def purchase(self, instance_count=1):
- return self.connection.purchase_reserved_instance_offering(self.id, instance_count)
+ def purchase(self, instance_count=1, dry_run=False):
+ return self.connection.purchase_reserved_instance_offering(
+ self.id,
+ instance_count,
+ dry_run=dry_run
+ )
class RecurringCharge(object):
diff --git a/boto/ec2/securitygroup.py b/boto/ec2/securitygroup.py
index 731c2390..3d93faa2 100644
--- a/boto/ec2/securitygroup.py
+++ b/boto/ec2/securitygroup.py
@@ -82,14 +82,21 @@ class SecurityGroup(TaggedEC2Object):
else:
setattr(self, name, value)
- def delete(self):
+ def delete(self, dry_run=False):
if self.vpc_id:
- return self.connection.delete_security_group(group_id=self.id)
+ return self.connection.delete_security_group(
+ group_id=self.id,
+ dry_run=dry_run
+ )
else:
- return self.connection.delete_security_group(self.name)
+ return self.connection.delete_security_group(
+ self.name,
+ dry_run=dry_run
+ )
def add_rule(self, ip_protocol, from_port, to_port,
- src_group_name, src_group_owner_id, cidr_ip, src_group_group_id):
+ src_group_name, src_group_owner_id, cidr_ip,
+ src_group_group_id, dry_run=False):
"""
Add a rule to the SecurityGroup object. Note that this method
only changes the local version of the object. No information
@@ -100,10 +107,17 @@ class SecurityGroup(TaggedEC2Object):
rule.from_port = from_port
rule.to_port = to_port
self.rules.append(rule)
- rule.add_grant(src_group_name, src_group_owner_id, cidr_ip, src_group_group_id)
+ rule.add_grant(
+ src_group_name,
+ src_group_owner_id,
+ cidr_ip,
+ src_group_group_id,
+ dry_run=dry_run
+ )
def remove_rule(self, ip_protocol, from_port, to_port,
- src_group_name, src_group_owner_id, cidr_ip, src_group_group_id):
+ src_group_name, src_group_owner_id, cidr_ip,
+ src_group_group_id, dry_run=False):
"""
Remove a rule to the SecurityGroup object. Note that this method
only changes the local version of the object. No information
@@ -122,12 +136,12 @@ class SecurityGroup(TaggedEC2Object):
if grant.cidr_ip == cidr_ip:
target_grant = grant
if target_grant:
- rule.grants.remove(target_grant)
+ rule.grants.remove(target_grant, dry_run=dry_run)
if len(rule.grants) == 0:
- self.rules.remove(target_rule)
+ self.rules.remove(target_rule, dry_run=dry_run)
def authorize(self, ip_protocol=None, from_port=None, to_port=None,
- cidr_ip=None, src_group=None):
+ cidr_ip=None, src_group=None, dry_run=False):
"""
Add a new rule to this security group.
You need to pass in either src_group_name
@@ -182,17 +196,19 @@ class SecurityGroup(TaggedEC2Object):
to_port,
cidr_ip,
group_id,
- src_group_group_id)
+ src_group_group_id,
+ dry_run=dry_run)
if status:
if not isinstance(cidr_ip, list):
cidr_ip = [cidr_ip]
for single_cidr_ip in cidr_ip:
self.add_rule(ip_protocol, from_port, to_port, src_group_name,
- src_group_owner_id, single_cidr_ip, src_group_group_id)
+ src_group_owner_id, single_cidr_ip,
+ src_group_group_id, dry_run=dry_run)
return status
def revoke(self, ip_protocol=None, from_port=None, to_port=None,
- cidr_ip=None, src_group=None):
+ cidr_ip=None, src_group=None, dry_run=False):
group_name = None
if not self.vpc_id:
group_name = self.name
@@ -220,13 +236,15 @@ class SecurityGroup(TaggedEC2Object):
to_port,
cidr_ip,
group_id,
- src_group_group_id)
+ src_group_group_id,
+ dry_run=dry_run)
if status:
self.remove_rule(ip_protocol, from_port, to_port, src_group_name,
- src_group_owner_id, cidr_ip, src_group_group_id)
+ src_group_owner_id, cidr_ip, src_group_group_id,
+ dry_run=dry_run)
return status
- def copy_to_region(self, region, name=None):
+ def copy_to_region(self, region, name=None, dry_run=False):
"""
Create a copy of this security group in another region.
Note that the new security group will be a separate entity
@@ -247,7 +265,11 @@ class SecurityGroup(TaggedEC2Object):
raise BotoClientError('Unable to copy to the same Region')
conn_params = self.connection.get_params()
rconn = region.connect(**conn_params)
- sg = rconn.create_security_group(name or self.name, self.description)
+ sg = rconn.create_security_group(
+ name or self.name,
+ self.description,
+ dry_run=dry_run
+ )
source_groups = []
for rule in self.rules:
for grant in rule.grants:
@@ -255,13 +277,14 @@ class SecurityGroup(TaggedEC2Object):
if grant_nom:
if grant_nom not in source_groups:
source_groups.append(grant_nom)
- sg.authorize(None, None, None, None, grant)
+ sg.authorize(None, None, None, None, grant,
+ dry_run=dry_run)
else:
sg.authorize(rule.ip_protocol, rule.from_port, rule.to_port,
- grant.cidr_ip)
+ grant.cidr_ip, dry_run=dry_run)
return sg
- def instances(self):
+ def instances(self, dry_run=False):
"""
Find all of the current instances that are running within this
security group.
@@ -272,11 +295,13 @@ class SecurityGroup(TaggedEC2Object):
rs = []
if self.vpc_id:
rs.extend(self.connection.get_all_reservations(
- filters={'instance.group-id': self.id}
+ filters={'instance.group-id': self.id},
+ dry_run=dry_run
))
else:
rs.extend(self.connection.get_all_reservations(
- filters={'group-id': self.id}
+ filters={'group-id': self.id},
+ dry_run=dry_run
))
instances = [i for r in rs for i in r.instances]
return instances
diff --git a/boto/ec2/snapshot.py b/boto/ec2/snapshot.py
index d2c4b2b9..24bffe6b 100644
--- a/boto/ec2/snapshot.py
+++ b/boto/ec2/snapshot.py
@@ -15,7 +15,7 @@
# 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,
+# 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.
@@ -27,9 +27,9 @@ from boto.ec2.ec2object import TaggedEC2Object
from boto.ec2.zone import Zone
class Snapshot(TaggedEC2Object):
-
+
AttrName = 'createVolumePermission'
-
+
def __init__(self, connection=None):
TaggedEC2Object.__init__(self, connection)
self.id = None
@@ -72,7 +72,7 @@ class Snapshot(TaggedEC2Object):
self.progress = updated.progress
self.status = updated.status
- def update(self, validate=False):
+ def update(self, validate=False, dry_run=False):
"""
Update the data associated with this snapshot by querying EC2.
@@ -83,39 +83,49 @@ class Snapshot(TaggedEC2Object):
raise a ValueError exception if no data is
returned from EC2.
"""
- rs = self.connection.get_all_snapshots([self.id])
+ rs = self.connection.get_all_snapshots([self.id], dry_run=dry_run)
if len(rs) > 0:
self._update(rs[0])
elif validate:
raise ValueError('%s is not a valid Snapshot ID' % self.id)
return self.progress
-
- def delete(self):
- return self.connection.delete_snapshot(self.id)
- def get_permissions(self):
- attrs = self.connection.get_snapshot_attribute(self.id, self.AttrName)
+ def delete(self, dry_run=False):
+ return self.connection.delete_snapshot(self.id, dry_run=dry_run)
+
+ def get_permissions(self, dry_run=False):
+ attrs = self.connection.get_snapshot_attribute(
+ self.id,
+ self.AttrName,
+ dry_run=dry_run
+ )
return attrs.attrs
- def share(self, user_ids=None, groups=None):
+ def share(self, user_ids=None, groups=None, dry_run=False):
return self.connection.modify_snapshot_attribute(self.id,
self.AttrName,
'add',
user_ids,
- groups)
+ groups,
+ dry_run=dry_run)
- def unshare(self, user_ids=None, groups=None):
+ def unshare(self, user_ids=None, groups=None, dry_run=False):
return self.connection.modify_snapshot_attribute(self.id,
self.AttrName,
'remove',
user_ids,
- groups)
-
- def reset_permissions(self):
- return self.connection.reset_snapshot_attribute(self.id,
- self.AttrName)
-
- def create_volume(self, zone, size=None, volume_type=None, iops=None):
+ groups,
+ dry_run=dry_run)
+
+ def reset_permissions(self, dry_run=False):
+ return self.connection.reset_snapshot_attribute(
+ self.id,
+ self.AttrName,
+ dry_run=dry_run
+ )
+
+ def create_volume(self, zone, size=None, volume_type=None, iops=None,
+ dry_run=False):
"""
Create a new EBS Volume from this Snapshot
@@ -136,7 +146,14 @@ class Snapshot(TaggedEC2Object):
"""
if isinstance(zone, Zone):
zone = zone.name
- return self.connection.create_volume(size, zone, self.id, volume_type, iops)
+ return self.connection.create_volume(
+ size,
+ zone,
+ self.id,
+ volume_type,
+ iops,
+ dry_run=dry_run
+ )
class SnapshotAttribute:
@@ -167,4 +184,4 @@ class SnapshotAttribute:
setattr(self, name, value)
-
+
diff --git a/boto/ec2/spotdatafeedsubscription.py b/boto/ec2/spotdatafeedsubscription.py
index 9b820a3e..1b30a99f 100644
--- a/boto/ec2/spotdatafeedsubscription.py
+++ b/boto/ec2/spotdatafeedsubscription.py
@@ -26,7 +26,7 @@ from boto.ec2.ec2object import EC2Object
from boto.ec2.spotinstancerequest import SpotInstanceStateFault
class SpotDatafeedSubscription(EC2Object):
-
+
def __init__(self, connection=None, owner_id=None,
bucket=None, prefix=None, state=None,fault=None):
EC2Object.__init__(self, connection)
@@ -45,7 +45,7 @@ class SpotDatafeedSubscription(EC2Object):
return self.fault
else:
return None
-
+
def endElement(self, name, value, connection):
if name == 'ownerId':
self.owner_id = value
@@ -58,6 +58,8 @@ class SpotDatafeedSubscription(EC2Object):
else:
setattr(self, name, value)
- def delete(self):
- return self.connection.delete_spot_datafeed_subscription()
+ def delete(self, dry_run=False):
+ return self.connection.delete_spot_datafeed_subscription(
+ dry_run=dry_run
+ )
diff --git a/boto/ec2/spotinstancerequest.py b/boto/ec2/spotinstancerequest.py
index 54fba1d6..c5b8bc95 100644
--- a/boto/ec2/spotinstancerequest.py
+++ b/boto/ec2/spotinstancerequest.py
@@ -184,5 +184,8 @@ class SpotInstanceRequest(TaggedEC2Object):
else:
setattr(self, name, value)
- def cancel(self):
- self.connection.cancel_spot_instance_requests([self.id])
+ def cancel(self, dry_run=False):
+ self.connection.cancel_spot_instance_requests(
+ [self.id],
+ dry_run=dry_run
+ )
diff --git a/boto/ec2/volume.py b/boto/ec2/volume.py
index bc5befc7..2127b260 100644
--- a/boto/ec2/volume.py
+++ b/boto/ec2/volume.py
@@ -98,7 +98,7 @@ class Volume(TaggedEC2Object):
def _update(self, updated):
self.__dict__.update(updated.__dict__)
- def update(self, validate=False):
+ def update(self, validate=False, dry_run=False):
"""
Update the data associated with this volume by querying EC2.
@@ -110,7 +110,10 @@ class Volume(TaggedEC2Object):
returned from EC2.
"""
# Check the resultset since Eucalyptus ignores the volumeId param
- unfiltered_rs = self.connection.get_all_volumes([self.id])
+ unfiltered_rs = self.connection.get_all_volumes(
+ [self.id],
+ dry_run=dry_run
+ )
rs = [x for x in unfiltered_rs if x.id == self.id]
if len(rs) > 0:
self._update(rs[0])
@@ -118,16 +121,16 @@ class Volume(TaggedEC2Object):
raise ValueError('%s is not a valid Volume ID' % self.id)
return self.status
- def delete(self):
+ def delete(self, dry_run=False):
"""
Delete this EBS volume.
:rtype: bool
:return: True if successful
"""
- return self.connection.delete_volume(self.id)
+ return self.connection.delete_volume(self.id, dry_run=dry_run)
- def attach(self, instance_id, device):
+ def attach(self, instance_id, device, dry_run=False):
"""
Attach this EBS volume to an EC2 instance.
@@ -142,9 +145,14 @@ class Volume(TaggedEC2Object):
:rtype: bool
:return: True if successful
"""
- return self.connection.attach_volume(self.id, instance_id, device)
-
- def detach(self, force=False):
+ return self.connection.attach_volume(
+ self.id,
+ instance_id,
+ device,
+ dry_run=dry_run
+ )
+
+ def detach(self, force=False, dry_run=False):
"""
Detach this EBS volume from an EC2 instance.
@@ -167,10 +175,15 @@ class Volume(TaggedEC2Object):
device = None
if self.attach_data:
device = self.attach_data.device
- return self.connection.detach_volume(self.id, instance_id,
- device, force)
-
- def create_snapshot(self, description=None):
+ return self.connection.detach_volume(
+ self.id,
+ instance_id,
+ device,
+ force,
+ dry_run=dry_run
+ )
+
+ def create_snapshot(self, description=None, dry_run=False):
"""
Create a snapshot of this EBS Volume.
@@ -181,7 +194,11 @@ class Volume(TaggedEC2Object):
:rtype: :class:`boto.ec2.snapshot.Snapshot`
:return: The created Snapshot object
"""
- return self.connection.create_snapshot(self.id, description)
+ return self.connection.create_snapshot(
+ self.id,
+ description,
+ dry_run=dry_run
+ )
def volume_state(self):
"""
@@ -198,7 +215,7 @@ class Volume(TaggedEC2Object):
state = self.attach_data.status
return state
- def snapshots(self, owner=None, restorable_by=None):
+ def snapshots(self, owner=None, restorable_by=None, dry_run=False):
"""
Get all snapshots related to this volume. Note that this requires
that all available snapshots for the account be retrieved from EC2
@@ -221,8 +238,11 @@ class Volume(TaggedEC2Object):
:return: The requested Snapshot objects
"""
- rs = self.connection.get_all_snapshots(owner=owner,
- restorable_by=restorable_by)
+ rs = self.connection.get_all_snapshots(
+ owner=owner,
+ restorable_by=restorable_by,
+ dry_run=dry_run
+ )
mine = []
for snap in rs:
if snap.volume_id == self.id:
diff --git a/boto/vpc/__init__.py b/boto/vpc/__init__.py
index 0e5eb3fb..24a93a74 100644
--- a/boto/vpc/__init__.py
+++ b/boto/vpc/__init__.py
@@ -83,7 +83,7 @@ class VPCConnection(EC2Connection):
# VPC methods
- def get_all_vpcs(self, vpc_ids=None, filters=None):
+ def get_all_vpcs(self, vpc_ids=None, filters=None, dry_run=False):
"""
Retrieve information about your VPCs. You can filter results to
return information only about those VPCs that match your search
@@ -102,6 +102,9 @@ class VPCConnection(EC2Connection):
* *cidrBlock* - a list CIDR blocks of the VPC
* *dhcpOptionsId* - a list of IDs of a set of DHCP options
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.vpc.VPC`
"""
@@ -110,37 +113,49 @@ class VPCConnection(EC2Connection):
self.build_list_params(params, vpc_ids, 'VpcId')
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeVpcs', params, [('item', VPC)])
- def create_vpc(self, cidr_block):
+ def create_vpc(self, cidr_block, dry_run=False):
"""
Create a new Virtual Private Cloud.
:type cidr_block: str
:param cidr_block: A valid CIDR block
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created VPC
:return: A :class:`boto.vpc.vpc.VPC` object
"""
params = {'CidrBlock' : cidr_block}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateVpc', params, VPC)
- def delete_vpc(self, vpc_id):
+ def delete_vpc(self, vpc_id, dry_run=False):
"""
Delete a Virtual Private Cloud.
:type vpc_id: str
:param vpc_id: The ID of the vpc to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'VpcId': vpc_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteVpc', params)
def modify_vpc_attribute(self, vpc_id,
enable_dns_support=None,
- enable_dns_hostnames=None):
+ enable_dns_hostnames=None, dry_run=False):
"""
Modifies the specified attribute of the specified VPC.
You can only modify one attribute at a time.
@@ -157,6 +172,10 @@ class VPCConnection(EC2Connection):
provided for the instances launched in this VPC. You can only
set this attribute to ``true`` if EnableDnsSupport
is also ``true``.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {'VpcId': vpc_id}
if enable_dns_support is not None:
@@ -169,11 +188,14 @@ class VPCConnection(EC2Connection):
params['EnableDnsHostnames.Value'] = 'true'
else:
params['EnableDnsHostnames.Value'] = 'false'
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ModifyVpcAttribute', params)
# Route Tables
- def get_all_route_tables(self, route_table_ids=None, filters=None):
+ def get_all_route_tables(self, route_table_ids=None, filters=None,
+ dry_run=False):
"""
Retrieve information about your routing tables. You can filter results
to return information only about those route tables that match your
@@ -188,6 +210,9 @@ class VPCConnection(EC2Connection):
:param filters: A list of tuples containing filters. Each tuple
consists of a filter key and a filter value.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.routetable.RouteTable`
"""
@@ -196,10 +221,12 @@ class VPCConnection(EC2Connection):
self.build_list_params(params, route_table_ids, "RouteTableId")
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeRouteTables', params,
[('item', RouteTable)])
- def associate_route_table(self, route_table_id, subnet_id):
+ def associate_route_table(self, route_table_id, subnet_id, dry_run=False):
"""
Associates a route table with a specific subnet.
@@ -209,6 +236,9 @@ class VPCConnection(EC2Connection):
:type subnet_id: str
:param subnet_id: The ID of the subnet to associate with.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: str
:return: The ID of the association created
"""
@@ -216,11 +246,12 @@ class VPCConnection(EC2Connection):
'RouteTableId': route_table_id,
'SubnetId': subnet_id
}
-
+ if dry_run:
+ params['DryRun'] = 'true'
result = self.get_object('AssociateRouteTable', params, ResultSet)
return result.associationId
- def disassociate_route_table(self, association_id):
+ def disassociate_route_table(self, association_id, dry_run=False):
"""
Removes an association from a route table. This will cause all subnets
that would've used this association to now use the main routing
@@ -229,40 +260,55 @@ class VPCConnection(EC2Connection):
:type association_id: str
:param association_id: The ID of the association to disassociate.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = { 'AssociationId': association_id }
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DisassociateRouteTable', params)
- def create_route_table(self, vpc_id):
+ def create_route_table(self, vpc_id, dry_run=False):
"""
Creates a new route table.
:type vpc_id: str
:param vpc_id: The VPC ID to associate this route table with.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created route table
:return: A :class:`boto.vpc.routetable.RouteTable` object
"""
params = { 'VpcId': vpc_id }
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateRouteTable', params, RouteTable)
- def delete_route_table(self, route_table_id):
+ def delete_route_table(self, route_table_id, dry_run=False):
"""
Delete a route table.
:type route_table_id: str
:param route_table_id: The ID of the route table to delete.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = { 'RouteTableId': route_table_id }
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteRouteTable', params)
def create_route(self, route_table_id, destination_cidr_block,
- gateway_id=None, instance_id=None):
+ gateway_id=None, instance_id=None, dry_run=False):
"""
Creates a new route in the route table within a VPC. The route's target
can be either a gateway attached to the VPC or a NAT instance in the
@@ -281,6 +327,9 @@ class VPCConnection(EC2Connection):
:type instance_id: str
:param instance_id: The ID of a NAT instance in your VPC.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -293,11 +342,14 @@ class VPCConnection(EC2Connection):
params['GatewayId'] = gateway_id
elif instance_id is not None:
params['InstanceId'] = instance_id
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('CreateRoute', params)
def replace_route(self, route_table_id, destination_cidr_block,
- gateway_id=None, instance_id=None, interface_id=None):
+ gateway_id=None, instance_id=None, interface_id=None,
+ dry_run=False):
"""
Replaces an existing route within a route table in a VPC.
@@ -317,6 +369,9 @@ class VPCConnection(EC2Connection):
:type interface_id: str
:param interface_id: Allows routing to network interface attachments.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -331,10 +386,13 @@ class VPCConnection(EC2Connection):
params['InstanceId'] = instance_id
elif interface_id is not None:
params['NetworkInterfaceId'] = interface_id
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('ReplaceRoute', params)
- def delete_route(self, route_table_id, destination_cidr_block):
+ def delete_route(self, route_table_id, destination_cidr_block,
+ dry_run=False):
"""
Deletes a route from a route table within a VPC.
@@ -345,6 +403,9 @@ class VPCConnection(EC2Connection):
:param destination_cidr_block: The CIDR address block used for
destination match.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -352,13 +413,14 @@ class VPCConnection(EC2Connection):
'RouteTableId': route_table_id,
'DestinationCidrBlock': destination_cidr_block
}
-
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteRoute', params)
# Internet Gateways
def get_all_internet_gateways(self, internet_gateway_ids=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Get a list of internet gateways. You can filter results to return information
about only those gateways that you're interested in.
@@ -369,6 +431,10 @@ class VPCConnection(EC2Connection):
:type filters: list of tuples
:param filters: A list of tuples containing filters. Each tuple
consists of a filter key and a filter value.
+
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
"""
params = {}
@@ -377,32 +443,46 @@ class VPCConnection(EC2Connection):
'InternetGatewayId')
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeInternetGateways', params,
[('item', InternetGateway)])
- def create_internet_gateway(self):
+ def create_internet_gateway(self, dry_run=False):
"""
Creates an internet gateway for VPC.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Newly created internet gateway.
:return: `boto.vpc.internetgateway.InternetGateway`
"""
- return self.get_object('CreateInternetGateway', {}, InternetGateway)
+ params = {}
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_object('CreateInternetGateway', params, InternetGateway)
- def delete_internet_gateway(self, internet_gateway_id):
+ def delete_internet_gateway(self, internet_gateway_id, dry_run=False):
"""
Deletes an internet gateway from the VPC.
:type internet_gateway_id: str
:param internet_gateway_id: The ID of the internet gateway to delete.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Bool
:return: True if successful
"""
params = { 'InternetGatewayId': internet_gateway_id }
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteInternetGateway', params)
- def attach_internet_gateway(self, internet_gateway_id, vpc_id):
+ def attach_internet_gateway(self, internet_gateway_id, vpc_id,
+ dry_run=False):
"""
Attach an internet gateway to a specific VPC.
@@ -412,6 +492,9 @@ class VPCConnection(EC2Connection):
:type vpc_id: str
:param vpc_id: The ID of the VPC to attach to.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Bool
:return: True if successful
"""
@@ -419,10 +502,12 @@ class VPCConnection(EC2Connection):
'InternetGatewayId': internet_gateway_id,
'VpcId': vpc_id
}
-
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AttachInternetGateway', params)
- def detach_internet_gateway(self, internet_gateway_id, vpc_id):
+ def detach_internet_gateway(self, internet_gateway_id, vpc_id,
+ dry_run=False):
"""
Detach an internet gateway from a specific VPC.
@@ -432,6 +517,9 @@ class VPCConnection(EC2Connection):
:type vpc_id: str
:param vpc_id: The ID of the VPC to attach to.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: Bool
:return: True if successful
"""
@@ -439,13 +527,14 @@ class VPCConnection(EC2Connection):
'InternetGatewayId': internet_gateway_id,
'VpcId': vpc_id
}
-
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DetachInternetGateway', params)
# Customer Gateways
def get_all_customer_gateways(self, customer_gateway_ids=None,
- filters=None):
+ filters=None, dry_run=False):
"""
Retrieve information about your CustomerGateways. You can filter
results to return information only about those CustomerGateways that
@@ -467,6 +556,9 @@ class VPCConnection(EC2Connection):
- *ipAddress* the IP address of customer gateway's
internet-routable external inteface
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.customergateway.CustomerGateway`
"""
@@ -477,10 +569,13 @@ class VPCConnection(EC2Connection):
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
+
return self.get_list('DescribeCustomerGateways', params,
[('item', CustomerGateway)])
- def create_customer_gateway(self, type, ip_address, bgp_asn):
+ def create_customer_gateway(self, type, ip_address, bgp_asn, dry_run=False):
"""
Create a new Customer Gateway
@@ -495,30 +590,41 @@ class VPCConnection(EC2Connection):
:param bgp_asn: Customer gateway's Border Gateway Protocol (BGP)
Autonomous System Number (ASN)
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created CustomerGateway
:return: A :class:`boto.vpc.customergateway.CustomerGateway` object
"""
params = {'Type' : type,
'IpAddress' : ip_address,
'BgpAsn' : bgp_asn}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateCustomerGateway', params, CustomerGateway)
- def delete_customer_gateway(self, customer_gateway_id):
+ def delete_customer_gateway(self, customer_gateway_id, dry_run=False):
"""
Delete a Customer Gateway.
:type customer_gateway_id: str
:param customer_gateway_id: The ID of the customer_gateway to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'CustomerGatewayId': customer_gateway_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteCustomerGateway', params)
# VPN Gateways
- def get_all_vpn_gateways(self, vpn_gateway_ids=None, filters=None):
+ def get_all_vpn_gateways(self, vpn_gateway_ids=None, filters=None,
+ dry_run=False):
"""
Retrieve information about your VpnGateways. You can filter results to
return information only about those VpnGateways that match your search
@@ -539,6 +645,9 @@ class VPCConnection(EC2Connection):
- *availabilityZone*, a list of Availability zones the
VPN gateway is in.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.customergateway.VpnGateway`
"""
@@ -547,10 +656,12 @@ class VPCConnection(EC2Connection):
self.build_list_params(params, vpn_gateway_ids, 'VpnGatewayId')
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeVpnGateways', params,
[('item', VpnGateway)])
- def create_vpn_gateway(self, type, availability_zone=None):
+ def create_vpn_gateway(self, type, availability_zone=None, dry_run=False):
"""
Create a new Vpn Gateway
@@ -560,28 +671,38 @@ class VPCConnection(EC2Connection):
:type availability_zone: str
:param availability_zone: The Availability Zone where you want the VPN gateway.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created VpnGateway
:return: A :class:`boto.vpc.vpngateway.VpnGateway` object
"""
params = {'Type' : type}
if availability_zone:
params['AvailabilityZone'] = availability_zone
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateVpnGateway', params, VpnGateway)
- def delete_vpn_gateway(self, vpn_gateway_id):
+ def delete_vpn_gateway(self, vpn_gateway_id, dry_run=False):
"""
Delete a Vpn Gateway.
:type vpn_gateway_id: str
:param vpn_gateway_id: The ID of the vpn_gateway to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'VpnGatewayId': vpn_gateway_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteVpnGateway', params)
- def attach_vpn_gateway(self, vpn_gateway_id, vpc_id):
+ def attach_vpn_gateway(self, vpn_gateway_id, vpc_id, dry_run=False):
"""
Attaches a VPN gateway to a VPC.
@@ -591,16 +712,21 @@ class VPCConnection(EC2Connection):
:type vpc_id: str
:param vpc_id: The ID of the VPC you want to attach the gateway to.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: An attachment
:return: a :class:`boto.vpc.vpngateway.Attachment`
"""
params = {'VpnGatewayId': vpn_gateway_id,
'VpcId' : vpc_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('AttachVpnGateway', params, Attachment)
# Subnets
- def get_all_subnets(self, subnet_ids=None, filters=None):
+ def get_all_subnets(self, subnet_ids=None, filters=None, dry_run=False):
"""
Retrieve information about your Subnets. You can filter results to
return information only about those Subnets that match your search
@@ -623,6 +749,9 @@ class VPCConnection(EC2Connection):
the subnet is in.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.subnet.Subnet`
"""
@@ -631,9 +760,12 @@ class VPCConnection(EC2Connection):
self.build_list_params(params, subnet_ids, 'SubnetId')
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeSubnets', params, [('item', Subnet)])
- def create_subnet(self, vpc_id, cidr_block, availability_zone=None):
+ def create_subnet(self, vpc_id, cidr_block, availability_zone=None,
+ dry_run=False):
"""
Create a new Subnet
@@ -646,6 +778,9 @@ class VPCConnection(EC2Connection):
:type availability_zone: str
:param availability_zone: The AZ you want the subnet in
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created Subnet
:return: A :class:`boto.vpc.customergateway.Subnet` object
"""
@@ -653,43 +788,55 @@ class VPCConnection(EC2Connection):
'CidrBlock' : cidr_block}
if availability_zone:
params['AvailabilityZone'] = availability_zone
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateSubnet', params, Subnet)
- def delete_subnet(self, subnet_id):
+ def delete_subnet(self, subnet_id, dry_run=False):
"""
Delete a subnet.
:type subnet_id: str
:param subnet_id: The ID of the subnet to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'SubnetId': subnet_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteSubnet', params)
# DHCP Options
- def get_all_dhcp_options(self, dhcp_options_ids=None):
+ def get_all_dhcp_options(self, dhcp_options_ids=None, dry_run=False):
"""
Retrieve information about your DhcpOptions.
:type dhcp_options_ids: list
:param dhcp_options_ids: A list of strings with the desired DhcpOption ID's
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpc.dhcpoptions.DhcpOptions`
"""
params = {}
if dhcp_options_ids:
self.build_list_params(params, dhcp_options_ids, 'DhcpOptionsId')
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeDhcpOptions', params,
[('item', DhcpOptions)])
def create_dhcp_options(self, domain_name=None, domain_name_servers=None,
ntp_servers=None, netbios_name_servers=None,
- netbios_node_type=None):
+ netbios_node_type=None, dry_run=False):
"""
Create a new DhcpOption
@@ -718,6 +865,9 @@ class VPCConnection(EC2Connection):
only use 2 at this time (broadcast and multicast are currently not
supported).
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created DhcpOption
:return: A :class:`boto.vpc.customergateway.DhcpOption` object
"""
@@ -753,23 +903,30 @@ class VPCConnection(EC2Connection):
if netbios_node_type:
key_counter = insert_option(params,
'netbios-node-type', netbios_node_type)
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateDhcpOptions', params, DhcpOptions)
- def delete_dhcp_options(self, dhcp_options_id):
+ def delete_dhcp_options(self, dhcp_options_id, dry_run=False):
"""
Delete a DHCP Options
:type dhcp_options_id: str
:param dhcp_options_id: The ID of the DHCP Options to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'DhcpOptionsId': dhcp_options_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteDhcpOptions', params)
- def associate_dhcp_options(self, dhcp_options_id, vpc_id):
+ def associate_dhcp_options(self, dhcp_options_id, vpc_id, dry_run=False):
"""
Associate a set of Dhcp Options with a VPC.
@@ -779,16 +936,22 @@ class VPCConnection(EC2Connection):
:type vpc_id: str
:param vpc_id: The ID of the VPC.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'DhcpOptionsId': dhcp_options_id,
'VpcId' : vpc_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('AssociateDhcpOptions', params)
# VPN Connection
- def get_all_vpn_connections(self, vpn_connection_ids=None, filters=None):
+ def get_all_vpn_connections(self, vpn_connection_ids=None, filters=None,
+ dry_run=False):
"""
Retrieve information about your VPN_CONNECTIONs. You can filter results to
return information only about those VPN_CONNECTIONs that match your search
@@ -811,6 +974,9 @@ class VPCConnection(EC2Connection):
- *vpnGatewayId*, a list of IDs of the VPN gateway associated
with the VPN connection
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: list
:return: A list of :class:`boto.vpn_connection.vpnconnection.VpnConnection`
"""
@@ -820,10 +986,13 @@ class VPCConnection(EC2Connection):
'Vpn_ConnectionId')
if filters:
self.build_filter_params(params, dict(filters))
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_list('DescribeVpnConnections', params,
[('item', VpnConnection)])
- def create_vpn_connection(self, type, customer_gateway_id, vpn_gateway_id):
+ def create_vpn_connection(self, type, customer_gateway_id, vpn_gateway_id,
+ dry_run=False):
"""
Create a new VPN Connection.
@@ -837,28 +1006,39 @@ class VPCConnection(EC2Connection):
:type vpn_gateway_id: str
:param vpn_gateway_id: The ID of the VPN gateway.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: The newly created VpnConnection
:return: A :class:`boto.vpc.vpnconnection.VpnConnection` object
"""
params = {'Type' : type,
'CustomerGatewayId' : customer_gateway_id,
'VpnGatewayId' : vpn_gateway_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_object('CreateVpnConnection', params, VpnConnection)
- def delete_vpn_connection(self, vpn_connection_id):
+ def delete_vpn_connection(self, vpn_connection_id, dry_run=False):
"""
Delete a VPN Connection.
:type vpn_connection_id: str
:param vpn_connection_id: The ID of the vpn_connection to be deleted.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
params = {'VpnConnectionId': vpn_connection_id}
+ if dry_run:
+ params['DryRun'] = 'true'
return self.get_status('DeleteVpnConnection', params)
- def disable_vgw_route_propagation(self, route_table_id, gateway_id):
+ def disable_vgw_route_propagation(self, route_table_id, gateway_id,
+ dry_run=False):
"""
Disables a virtual private gateway (VGW) from propagating routes to the
routing tables of an Amazon VPC.
@@ -869,6 +1049,9 @@ class VPCConnection(EC2Connection):
:type gateway_id: str
:param gateway_id: The ID of the virtual private gateway.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -876,9 +1059,12 @@ class VPCConnection(EC2Connection):
'RouteTableId': route_table_id,
'GatewayId': gateway_id,
}
- self.get_status('DisableVgwRoutePropagation', params)
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_status('DisableVgwRoutePropagation', params)
- def enable_vgw_route_propagation(self, route_table_id, gateway_id):
+ def enable_vgw_route_propagation(self, route_table_id, gateway_id,
+ dry_run=False):
"""
Enables a virtual private gateway (VGW) to propagate routes to the
routing tables of an Amazon VPC.
@@ -889,6 +1075,9 @@ class VPCConnection(EC2Connection):
:type gateway_id: str
:param gateway_id: The ID of the virtual private gateway.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -896,10 +1085,12 @@ class VPCConnection(EC2Connection):
'RouteTableId': route_table_id,
'GatewayId': gateway_id,
}
- self.get_status('EnableVgwRoutePropagation', params)
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_status('EnableVgwRoutePropagation', params)
def create_vpn_connection_route(self, destination_cidr_block,
- vpn_connection_id):
+ vpn_connection_id, dry_run=False):
"""
Creates a new static route associated with a VPN connection between an
existing virtual private gateway and a VPN customer gateway. The static
@@ -913,6 +1104,9 @@ class VPCConnection(EC2Connection):
:type vpn_connection_id: str
:param vpn_connection_id: The ID of the VPN connection.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -920,10 +1114,12 @@ class VPCConnection(EC2Connection):
'DestinationCidrBlock': destination_cidr_block,
'VpnConnectionId': vpn_connection_id,
}
- self.get_status('CreateVpnConnectionRoute', params)
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_status('CreateVpnConnectionRoute', params)
def delete_vpn_connection_route(self, destination_cidr_block,
- vpn_connection_id):
+ vpn_connection_id, dry_run=False):
"""
Deletes a static route associated with a VPN connection between an
existing virtual private gateway and a VPN customer gateway. The static
@@ -937,6 +1133,9 @@ class VPCConnection(EC2Connection):
:type vpn_connection_id: str
:param vpn_connection_id: The ID of the VPN connection.
+ :type dry_run: bool
+ :param dry_run: Set to True if the operation should not actually run.
+
:rtype: bool
:return: True if successful
"""
@@ -944,4 +1143,6 @@ class VPCConnection(EC2Connection):
'DestinationCidrBlock': destination_cidr_block,
'VpnConnectionId': vpn_connection_id,
}
- self.get_status('DeleteVpnConnectionRoute', params)
+ if dry_run:
+ params['DryRun'] = 'true'
+ return self.get_status('DeleteVpnConnectionRoute', params)
diff --git a/boto/vpc/vpc.py b/boto/vpc/vpc.py
index 8fdaa62f..2eb480d1 100644
--- a/boto/vpc/vpc.py
+++ b/boto/vpc/vpc.py
@@ -72,8 +72,11 @@ class VPC(TaggedEC2Object):
def _update(self, updated):
self.__dict__.update(updated.__dict__)
- def update(self, validate=False):
- vpc_list = self.connection.get_all_vpcs([self.id])
+ def update(self, validate=False, dry_run=False):
+ vpc_list = self.connection.get_all_vpcs(
+ [self.id],
+ dry_run=dry_run
+ )
if len(vpc_list):
updated_vpc = vpc_list[0]
self._update(updated_vpc)
diff --git a/boto/vpc/vpnconnection.py b/boto/vpc/vpnconnection.py
index aa49c36a..c36492f5 100644
--- a/boto/vpc/vpnconnection.py
+++ b/boto/vpc/vpnconnection.py
@@ -197,5 +197,8 @@ class VpnConnection(TaggedEC2Object):
else:
setattr(self, name, value)
- def delete(self):
- return self.connection.delete_vpn_connection(self.id)
+ def delete(self, dry_run=False):
+ return self.connection.delete_vpn_connection(
+ self.id,
+ dry_run=dry_run
+ )
diff --git a/boto/vpc/vpngateway.py b/boto/vpc/vpngateway.py
index 83b912ef..fe476d93 100644
--- a/boto/vpc/vpngateway.py
+++ b/boto/vpc/vpngateway.py
@@ -14,7 +14,7 @@
# 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,
+# 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.
@@ -33,7 +33,7 @@ class Attachment(object):
def startElement(self, name, attrs, connection):
pass
-
+
def endElement(self, name, value, connection):
if name == 'vpcId':
self.vpc_id = value
@@ -41,7 +41,7 @@ class Attachment(object):
self.state = value
else:
setattr(self, name, value)
-
+
class VpnGateway(TaggedEC2Object):
def __init__(self, connection=None):
@@ -63,7 +63,7 @@ class VpnGateway(TaggedEC2Object):
att = Attachment()
self.attachments.append(att)
return att
-
+
def endElement(self, name, value, connection):
if name == 'vpnGatewayId':
self.id = value
@@ -78,6 +78,10 @@ class VpnGateway(TaggedEC2Object):
else:
setattr(self, name, value)
- def attach(self, vpc_id):
- return self.connection.attach_vpn_gateway(self.id, vpc_id)
+ def attach(self, vpc_id, dry_run=False):
+ return self.connection.attach_vpn_gateway(
+ self.id,
+ vpc_id,
+ dry_run=dry_run
+ )
diff --git a/tests/integration/ec2/test_connection.py b/tests/integration/ec2/test_connection.py
index ef1080b0..fc7137ab 100644
--- a/tests/integration/ec2/test_connection.py
+++ b/tests/integration/ec2/test_connection.py
@@ -32,9 +32,10 @@ import socket
from nose.plugins.attrib import attr
from boto.ec2.connection import EC2Connection
+from boto.exception import EC2ResponseError
-class EC2ConnectionTest (unittest.TestCase):
+class EC2ConnectionTest(unittest.TestCase):
ec2 = True
@attr('notdefault')
@@ -190,3 +191,51 @@ class EC2ConnectionTest (unittest.TestCase):
assert l[0].product_codes[0] == demo_paid_ami_product_code
print '--- tests completed ---'
+
+ def test_dry_run(self):
+ c = EC2Connection()
+ dry_run_msg = 'Request would have succeeded, but DryRun flag is set.'
+
+ try:
+ rs = c.get_all_images(dry_run=True)
+ self.fail("Should have gotten an exception")
+ except EC2ResponseError, e:
+ self.assertTrue(dry_run_msg in str(e))
+
+ try:
+ rs = c.run_instances(
+ image_id='ami-a0cd60c9',
+ instance_type='m1.small',
+ dry_run=True
+ )
+ self.fail("Should have gotten an exception")
+ except EC2ResponseError, e:
+ self.assertTrue(dry_run_msg in str(e))
+
+ # Need an actual instance for the rest of this...
+ rs = c.run_instances(
+ image_id='ami-a0cd60c9',
+ instance_type='m1.small'
+ )
+ time.sleep(120)
+
+ try:
+ rs = c.stop_instances(
+ instance_ids=[rs.instances[0].id],
+ dry_run=True
+ )
+ self.fail("Should have gotten an exception")
+ except EC2ResponseError, e:
+ self.assertTrue(dry_run_msg in str(e))
+
+ try:
+ rs = c.terminate_instances(
+ instance_ids=[rs.instances[0].id],
+ dry_run=True
+ )
+ self.fail("Should have gotten an exception")
+ except EC2ResponseError, e:
+ self.assertTrue(dry_run_msg in str(e))
+
+ # And kill it.
+ rs.instances[0].terminate()