Skip to content

Commit

Permalink
Merge branch 'release/0.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Dahlgren committed Jan 18, 2015
2 parents 2f3187d + c23e138 commit 13553f8
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 3 deletions.
37 changes: 37 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ created daily.

automated-ebs-snapshots --config ~/auto-ebs-snapshots.conf --watch vol-12345678 --interval daily

Add volumes to watch list
^^^^^^^^^^^^^^^^^^^^^^^^^

To add lots of volumes in one time, we can create a configuration file to define volumes(support volume id or Name tag), interval and retention.
::

vol-d9d6d6af,weekly,2
volume1,weekly,4
volume2,daily,0

Then run the following command
::

automated-ebs-snapshots --config ~/auto-ebs-snapshots.conf --watch-file volumes.conf

List watched volumes
^^^^^^^^^^^^^^^^^^^^

Expand All @@ -81,6 +96,22 @@ To stop creating automated backups for a volume, run this:

automated-ebs-snapshots --config ~/automated-ebs-snapshots.conf --unwatch vol-12345678

Remove volumes from watch list
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To remove all volumes in the configuration file, just run:
::

automated-ebs-snapshots --config ~/auto-ebs-snapshots.conf --unwatch-file volumes.conf

List snapshots for a volume
^^^^^^^^^^^^^^^^^^^^^^^^^^^

List all snapshots for the given volume id or volume name
::

automated-ebs-snapshots --config ~/automated-ebs-snapshots.conf --snapshots vol-d9d6d6af

Creating snapshots
------------------

Expand Down Expand Up @@ -116,6 +147,12 @@ You can also restart it using
Release notes
-------------

0.4.0
^^^^^

- Added support for reading volumes from file (`#13 <https://github.com/skymill/automated-ebs-snapshots/issues/13>`__). Thanks `@yumminhuang <https://github.com/yumminhuang>`__ for the pull request
- Now supports managing volumes by tag `Name` in addition to `volume-id` (`#13 <https://github.com/skymill/automated-ebs-snapshots/issues/13>`__). Thanks `@yumminhuang <https://github.com/yumminhuang>`__ for the pull request

0.3.2
^^^^^

Expand Down
9 changes: 9 additions & 0 deletions automated_ebs_snapshots/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@ def main():
if args.unwatch:
volume_manager.unwatch(connection, args.unwatch)

if args.watch_file:
volume_manager.watch_from_file(connection, args.watch_file)

if args.unwatch_file:
volume_manager.unwatch_from_file(connection, args.unwatch_file)

if args.snapshots:
volume_manager.list_snapshots(connection, args.snapshots)

if args.list:
volume_manager.list(connection)

Expand Down
17 changes: 17 additions & 0 deletions automated_ebs_snapshots/command_line_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@
help=(
'Add a new EBS volume to the watch list. '
'Usage: --watch vol-12345678'))
admin_actions_ag.add_argument(
'--snapshots',
metavar='VOLUME',
help='List all snapshots of this EBS volume')
admin_actions_ag.add_argument(
'--unwatch-file',
metavar='FILE_NAME',
help=(
'Remove all EBS volumes in the config file from the watch list. '
'Usage: --unwatch-file volumes.conf'))
admin_actions_ag.add_argument(
'--watch-file',
metavar='FILE_NAME',
help=(
'Add all EBS volumes in the config file to the watch list. '
'Usage: --watch-file volumes.conf'))

actions_ag = parser.add_argument_group(
title='Actions')
actions_ag.add_argument(
Expand Down
2 changes: 1 addition & 1 deletion automated_ebs_snapshots/settings.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[general]
version: 0.3.2
version: 0.4.0
121 changes: 119 additions & 2 deletions automated_ebs_snapshots/volume_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
""" Handle EBS volumes """
import logging
import re

from boto.exception import EC2ResponseError

from automated_ebs_snapshots.valid_intervals import VALID_INTERVALS

Expand Down Expand Up @@ -99,7 +102,7 @@ def unwatch(connection, volume_id):
try:
volume = connection.get_all_volumes(volume_ids=[volume_id])[0]
volume.remove_tag('AutomatedEBSSnapshots')
except KeyError:
except EC2ResponseError:
pass

logger.info('Removed {} from the watchlist'.format(volume_id))
Expand All @@ -122,7 +125,7 @@ def watch(connection, volume_id, interval='daily', retention=0):
"""
try:
volume = connection.get_all_volumes(volume_ids=[volume_id])[0]
except KeyError:
except EC2ResponseError:
logger.warning('Volume {} not found'.format(volume_id))
return False

Expand All @@ -147,3 +150,117 @@ def watch(connection, volume_id, interval='daily', retention=0):
interval, volume_id))

return True


def get_volume_id(connection, volume):
"""
Get Volume ID from the given volume. Input can be volume id
or its Name tag.
:type connection: boto.ec2.connection.EC2Connection
:param connection: EC2 connection object
:type volume: str
:param volume: Volume ID or Volume Name
:returns: Volume ID or None if the given volume does not exist
"""
# Regular expression to check whether input is a volume id
volume_id_pattern = re.compile('vol-\w{8}')

if volume_id_pattern.match(volume):
# input is volume id
try:
# Check whether it exists
connection.get_all_volumes(volume_ids=[volume])
volume_id = volume
except EC2ResponseError:
logger.warning('Volume {} not found'.format(volume))
return None
else:
# input is volume name
name_filter = {'tag-key': 'Name', 'tag-value': volume}
volumes = connection.get_all_volumes(filters=name_filter)
if not volumes:
logger.warning('Volume {} not found'.format(volume))
return None
if len(volumes) > 1:
logger.warning('Volume {} not unique'.format(volume))
volume_id = volumes[0].id

return volume_id


def watch_from_file(connection, file_name):
""" Start watching a new volume
:type connection: boto.ec2.connection.EC2Connection
:param connection: EC2 connection object
:type file_name: str
:param file_name: path to config file
:returns: None
"""
with open(file_name, 'r') as filehandle:
for line in filehandle.xreadlines():
volume, interval, retention = line.rstrip().split(',')
watch(
connection,
get_volume_id(connection, volume),
interval, retention)


def unwatch_from_file(connection, file_name):
""" Start watching a new volume
:type connection: boto.ec2.connection.EC2Connection
:param connection: EC2 connection object
:type file_name: str
:param file_name: path to config file
:returns: None
"""
with open(file_name, 'r') as filehandle:
for line in filehandle.xreadlines():
volume, interval, retention = line.rstrip().split(',')
unwatch(connection, get_volume_id(connection, volume))


def list_snapshots(connection, volume):
""" List all snapshots for the volume
:type connection: boto.ec2.connection.EC2Connection
:param connection: EC2 connection object
:type volume: str
:param volume: Volume ID or Volume Name
:returns: None
"""

logger.info(
'+----------------'
'+----------------------'
'+---------------------------+')
logger.info(
'| {snapshot:<14} '
'| {snapshot_name:<20.20} '
'| {created:<25} |'.format(
snapshot='Snapshot ID',
snapshot_name='Snapshot name',
created='Created'))
logger.info(
'+----------------'
'+----------------------'
'+---------------------------+')

vid = get_volume_id(connection, volume)
if vid:
vol = connection.get_all_volumes(volume_ids=[vid])[0]
for snap in vol.snapshots():
logger.info(
'| {snapshot:<14} '
'| {snapshot_name:<20.20} '
'| {created:<25} |'.format(
snapshot=snap.id,
snapshot_name=snap.tags.get('Name', ''),
created=snap.start_time))

logger.info(
'+----------------'
'+----------------------'
'+---------------------------+')
3 changes: 3 additions & 0 deletions volumes.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vol-d9d6d6af,weekly,2
volume1,weekly,4
volume2,daily,0

0 comments on commit 13553f8

Please sign in to comment.