def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img is None: module.fail_json(msg="Image %s does not exist" % image_id, changed=False) # Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable snapshots = [] if hasattr(img, 'block_device_mapping'): for key in img.block_device_mapping: snapshots.append(img.block_device_mapping[key].snapshot_id) # When trying to re-delete already deleted image it doesn't raise an exception # It just returns an object without image attributes if hasattr(img, 'id'): try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} ec2.deregister_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) else: module.exit_json(msg="Image %s has already been deleted" % image_id, changed=False) # wait here until the image is gone img = ec2.get_image(image_id) wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and img is not None: img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time(): # waiting took too long module.fail_json( msg="timed out waiting for image to be deregistered/deleted") # Boto library has hardcoded the deletion of the snapshot for the root volume mounted as '/dev/sda1' only # Make it possible to delete all snapshots which belong to image, including root block device mapped as '/dev/xvda' if delete_snapshot: try: for snapshot_id in snapshots: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: if e.error_code == 'InvalidSnapshot.NotFound': # Don't error out if root volume snapshot was already deleted as part of deregister_image pass module.exit_json(msg="AMI deregister/delete operation complete", changed=True, snapshots_deleted=snapshots) else: module.exit_json(msg="AMI deregister/delete operation complete", changed=True)
def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img is None: module.fail_json(msg="Image %s does not exist" % image_id, changed=False) # Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable snapshots = [] if hasattr(img, 'block_device_mapping'): for key in img.block_device_mapping: snapshots.append(img.block_device_mapping[key].snapshot_id) # When trying to re-delete already deleted image it doesn't raise an exception # It just returns an object without image attributes if hasattr(img, 'id'): try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} ec2.deregister_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) else: module.exit_json(msg="Image %s has already been deleted" % image_id, changed=False) # wait here until the image is gone img = ec2.get_image(image_id) wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and img is not None: img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time(): # waiting took too long module.fail_json(msg="timed out waiting for image to be deregistered/deleted") # Boto library has hardcoded the deletion of the snapshot for the root volume mounted as '/dev/sda1' only # Make it possible to delete all snapshots which belong to image, including root block device mapped as '/dev/xvda' if delete_snapshot: try: for snapshot_id in snapshots: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: if e.error_code == 'InvalidSnapshot.NotFound': # Don't error out if root volume snapshot was already deleted as part of deregister_image pass module.exit_json(msg="AMI deregister/delete operation complete", changed=True, snapshots_deleted=snapshots) else: module.exit_json(msg="AMI deregister/delete operation complete", changed=True)
def snapshots(aws_region, days, ss_delete): try: ec2 = boto.ec2.connect_to_region(aws_region) ebs_snapshots = ec2.get_all_snapshots(owner=['self']) for ebs_ss in ebs_snapshots: try: date_now = str(datetime.datetime.now().strftime('%Y-%m-%d')) snapshot_time = str(ebs_ss.start_time).split("T") date_delta = date_compare(snapshot_time[0], date_now) if date_delta >= days: print ebs_ss.id if ss_delete: try: ec2.delete_snapshot(ebs_ss.id) print "deleting.\n" except Exception, e: print e.response except Exception, e: print e except KeyboardInterrupt: sys.exit(0) except Exception, e: print e
def create_snapshot(module, ec2, state=None, description=None, wait=None, wait_timeout=None, volume_id=None, instance_id=None, snapshot_id=None, device_name=None, snapshot_tags=None, last_snapshot_min_age=None): snapshot = None changed = False required = [volume_id, snapshot_id, instance_id] if required.count(None) != len(required) - 1: # only 1 must be set module.fail_json(msg='One and only one of volume_id or instance_id or snapshot_id must be specified') if instance_id and not device_name or device_name and not instance_id: module.fail_json(msg='Instance ID and device name must both be specified') if instance_id: try: volumes = ec2.get_all_volumes(filters={'attachment.instance-id': instance_id, 'attachment.device': device_name}) except boto.exception.BotoServerError as e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) if not volumes: module.fail_json(msg="Could not find volume with name %s attached to instance %s" % (device_name, instance_id)) volume_id = volumes[0].id if state == 'absent': if not snapshot_id: module.fail_json(msg = 'snapshot_id must be set when state is absent') try: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: # exception is raised if snapshot does not exist if e.error_code == 'InvalidSnapshot.NotFound': module.exit_json(changed=False) else: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) # successful delete module.exit_json(changed=True) if last_snapshot_min_age > 0: try: current_snapshots = ec2.get_all_snapshots(filters={'volume_id': volume_id}) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) last_snapshot_min_age = last_snapshot_min_age * 60 # Convert to seconds snapshot = _get_most_recent_snapshot(current_snapshots, max_snapshot_age_secs=last_snapshot_min_age) try: # Create a new snapshot if we didn't find an existing one to use if snapshot is None: snapshot = ec2.create_snapshot(volume_id, description=description) changed = True if wait: if not _create_with_wait(snapshot, wait_timeout): module.fail_json(msg='Timed out while creating snapshot.') if snapshot_tags: for k, v in snapshot_tags.items(): snapshot.add_tag(k, v) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) module.exit_json(changed=changed, snapshot_id=snapshot.id, volume_id=snapshot.volume_id, volume_size=snapshot.volume_size, tags=snapshot.tags.copy())
if instance_id: try: volumes = ec2.get_all_volumes(filters={'attachment.instance-id': instance_id, 'attachment.device': device_name}) except boto.exception.BotoServerError, e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) if not volumes: module.fail_json(msg="Could not find volume with name %s attached to instance %s" % (device_name, instance_id)) volume_id = volumes[0].id if state == 'absent': if not snapshot_id: module.fail_json(msg = 'snapshot_id must be set when state is absent') try: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError, e: # exception is raised if snapshot does not exist if e.error_code == 'InvalidSnapshot.NotFound': module.exit_json(changed=False) else: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message)) # successful delete module.exit_json(changed=True) if last_snapshot_min_age > 0: try: current_snapshots = ec2.get_all_snapshots(filters={'volume_id': volume_id}) except boto.exception.BotoServerError, e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
parser = argparse.ArgumentParser(description='Delete EBS snapshots in all/some available EC2 regions', parents=[bc.build_region_parser(), bc.build_filter_parser('EBS snapshot'), bc.build_common_parser()]) args = parser.parse_args() # process common command line arguments log = logging.getLogger('botocross') bc.configure_logging(log, args.log_level) credentials = bc.parse_credentials(args) regions = bc.filter_regions(boto.ec2.regions(), args.region) filter = bc.build_filter(args.filter, args.exclude) log.info(args.resource_ids) # execute business logic log.info("Deleting EBS snapshots:") for region in regions: try: ec2 = boto.connect_ec2(region=region, **credentials) snapshots = ec2.get_all_snapshots(snapshot_ids=args.resource_ids, owner='self', filters=filter['filters']) if filter['excludes']: exclusions = ec2.get_all_snapshots(owner='self', filters=filter['excludes']) snapshots = bc.filter_list_by_attribute(snapshots, exclusions, 'id') print region.name + ": " + str(len(snapshots)) + " EBS snapshots" for snapshot in snapshots: if args.verbose: print snapshot.id else: ec2.delete_snapshot(snapshot.id) except boto.exception.BotoServerError, e: log.error(e.error_message)
def create_snapshot(module, ec2, state=None, description=None, wait=None, wait_timeout=None, volume_id=None, instance_id=None, snapshot_id=None, device_name=None, snapshot_tags=None, last_snapshot_min_age=None): snapshot = None changed = False required = [volume_id, snapshot_id, instance_id] if required.count(None) != len(required) - 1: # only 1 must be set module.fail_json( msg= 'One and only one of volume_id or instance_id or snapshot_id must be specified' ) if instance_id and not device_name or device_name and not instance_id: module.fail_json( msg='Instance ID and device name must both be specified') if instance_id: try: volumes = ec2.get_all_volumes( filters={ 'attachment.instance-id': instance_id, 'attachment.device': device_name }) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) if not volumes: module.fail_json( msg="Could not find volume with name %s attached to instance %s" % (device_name, instance_id)) volume_id = volumes[0].id if state == 'absent': if not snapshot_id: module.fail_json( msg='snapshot_id must be set when state is absent') try: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: # exception is raised if snapshot does not exist if e.error_code == 'InvalidSnapshot.NotFound': module.exit_json(changed=False) else: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # successful delete module.exit_json(changed=True) if last_snapshot_min_age > 0: try: current_snapshots = ec2.get_all_snapshots( filters={'volume_id': volume_id}) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) last_snapshot_min_age = last_snapshot_min_age * 60 # Convert to seconds snapshot = _get_most_recent_snapshot( current_snapshots, max_snapshot_age_secs=last_snapshot_min_age) try: # Create a new snapshot if we didn't find an existing one to use if snapshot is None: snapshot = ec2.create_snapshot(volume_id, description=description) changed = True if wait: if not _create_with_wait(snapshot, wait_timeout): module.fail_json(msg='Timed out while creating snapshot.') if snapshot_tags: for k, v in snapshot_tags.items(): snapshot.add_tag(k, v) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) module.exit_json(changed=changed, snapshot_id=snapshot.id, volume_id=snapshot.volume_id, volume_size=snapshot.volume_size, tags=snapshot.tags.copy())
def create_snapshot(module, ec2, state=None, description=None, wait=None, wait_timeout=None, volume_id=None, instance_id=None, snapshot_id=None, device_name=None, snapshot_tags=None, last_snapshot_min_age=None, create_volume_permissions=None): snapshot = None changed = False if instance_id: try: volumes = ec2.get_all_volumes( filters={ 'attachment.instance-id': instance_id, 'attachment.device': device_name }) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) if not volumes: module.fail_json( msg="Could not find volume with name %s attached to instance %s" % (device_name, instance_id)) volume_id = volumes[0].id if state == 'absent': try: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: # exception is raised if snapshot does not exist if e.error_code == 'InvalidSnapshot.NotFound': module.exit_json(changed=False) else: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # successful delete module.exit_json(changed=True) if last_snapshot_min_age > 0: try: current_snapshots = ec2.get_all_snapshots( filters={'volume_id': volume_id}) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) last_snapshot_min_age = last_snapshot_min_age * 60 # Convert to seconds snapshot = _get_most_recent_snapshot( current_snapshots, max_snapshot_age_secs=last_snapshot_min_age) try: if snapshot_id: snapshot = ec2.get_all_snapshots(snapshot_ids=[snapshot_id])[0] # Create a new snapshot if we didn't find an existing one to use if snapshot is None: snapshot = ec2.create_snapshot(volume_id, description=description) changed = True if wait: if not _create_with_wait(snapshot, wait_timeout): module.fail_json(msg='Timed out while creating snapshot.') if snapshot_tags: tags_to_add, tags_to_remove = existing_to_desired( snapshot.tags.items(), snapshot_tags.items()) for (k, v) in tags_to_add: snapshot.add_tag(k, v) changed = True for (k, v) in tags_to_remove: snapshot.remove_tag(k, value=v) changed = True permissions = ec2.get_snapshot_attribute(snapshot.id) users_to_add, users_to_remove = existing_to_desired( permissions.attrs.get('user_ids', []), [ str(user_id) for user_id in create_volume_permissions.get('user_ids', []) ]) groups_to_add, groups_to_remove = existing_to_desired( permissions.attrs.get('groups', []), create_volume_permissions.get('groups', [])) if users_to_add or groups_to_add: ec2.modify_snapshot_attribute(snapshot.id, user_ids=users_to_add, groups=groups_to_add) permissions = ec2.get_snapshot_attribute(snapshot.id) changed = True if users_to_remove or groups_to_remove: ec2.modify_snapshot_attribute(snapshot.id, operation='remove', user_ids=users_to_remove, groups=groups_to_remove) permissions = ec2.get_snapshot_attribute(snapshot.id) changed = True except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) module.exit_json(changed=changed, snapshot_id=snapshot.id, volume_id=snapshot.volume_id, volume_size=snapshot.volume_size, tags=snapshot.tags.copy(), permissions=permissions.attrs)
def deleteSnap(self): try: ec2.delete_snapshot(self.snap) except: logger.error('Could not delete snapshot: %s for volume: %s' % (self.snap, self.snapVolume()))
# process common command line arguments log = logging.getLogger('botocross') bc.configure_logging(log, args.log_level) credentials = bc.parse_credentials(args) regions = bc.filter_regions(boto.ec2.regions(), args.region) filter = bc.build_filter(args.filter, args.exclude) log.info(args.resource_ids) # execute business logic log.info("Deleting EBS snapshots:") for region in regions: try: ec2 = boto.connect_ec2(region=region, **credentials) snapshots = ec2.get_all_snapshots(snapshot_ids=args.resource_ids, owner='self', filters=filter['filters']) if filter['excludes']: exclusions = ec2.get_all_snapshots(owner='self', filters=filter['excludes']) snapshots = bc.filter_list_by_attribute(snapshots, exclusions, 'id') print region.name + ": " + str(len(snapshots)) + " EBS snapshots" for snapshot in snapshots: if args.verbose: print snapshot.id else: ec2.delete_snapshot(snapshot.id) except boto.exception.BotoServerError, e: log.error(e.error_message)