def run(): parser = argparse.ArgumentParser(description='Loops through all EBS volumes, and snapshots them, then loops through all snapshots, and removes the oldest ones.') parser.add_argument('--region', metavar='REGION', help='the region to loop through and snapshot (default is current region of EC2 instance this is running on). E.g. us-east-1') parser.add_argument('--max-snapshots-per-volume', metavar='SNAPSHOTS', default=3, type=int, help='the maximum number of snapshots to keep per EBS volume. The oldest snapshots will be deleted. Default: 3') parser.add_argument('--snapshot-only', action='store_true', default=False, help='Only snapshot EBS volumes, do not remove old snapshots') parser.add_argument('--remove-only', action='store_true', default=False, help='Only remove old snapshots, do not create new snapshots') parser.add_argument('--verbose', '-v', action='count', help='enable verbose output (-vvv for more)') parser.add_argument('--version', action='version', version='%(prog)s ' + __version__, help='display version number and exit') args = parser.parse_args() Logging().configure(args.verbose) log.debug("CLI parse args: %s", args) if args.region: region = args.region else: # If no region was specified, assume this is running on an EC2 instance # and work out what region it is in log.debug("Figure out which region I am running in...") instance_metadata = get_instance_metadata(timeout=5) log.debug('Instance meta-data: %s', instance_metadata) if not instance_metadata: _fail('Could not determine region. This script is either not running on an EC2 instance (in which case you should use the --region option), or the meta-data service is down') region = instance_metadata['placement']['availability-zone'][:-1] log.debug("Running in region: %s", region) try: monkey = BackupMonkey(region, args.max_snapshots_per_volume) if not args.remove_only: monkey.snapshot_volumes() if not args.snapshot_only: monkey.remove_old_snapshots() except BackupMonkeyException as e: _fail(e.message) log.info('Backup Monkey completed successfully!') sys.exit(0)
class LabelTest(TestCase): @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def setUp(self, mock): self.bm = BackupMonkey('us-west-2', 1, [], None, None, None, None) self.bm_with_label_daily = BackupMonkey('us-west-2', 1, [], None, 'daily', None, None) self.bm_with_label_weekly = BackupMonkey('us-west-2', 1, [], None, 'weekly', None, None) @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_without_label(self, mock): snaps = self.bm._conn.get_all_snapshots() init_snapshot = filter(lambda x: x.status == 'completed', snaps) self.bm.remove_old_snapshots() snaps = self.bm._conn.get_all_snapshots() end_snapshot = filter(lambda x: x.status == 'completed', snaps) assert len(init_snapshot) == 4 assert len(end_snapshot) == 2 @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_with_label_daily(self, mock): snaps = self.bm_with_label_daily._conn.get_all_snapshots() init_snapshot = filter(lambda x: x.status == 'completed', snaps) self.bm_with_label_daily.remove_old_snapshots() snaps = self.bm_with_label_daily._conn.get_all_snapshots() end_snapshot = filter(lambda x: x.status == 'completed', snaps) assert len(init_snapshot) == 4 assert len(end_snapshot) == 4 @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_with_label_weekly(self, mock): snaps = self.bm_with_label_weekly._conn.get_all_snapshots() init_snapshot = filter(lambda x: x.status == 'completed', snaps) self.bm_with_label_weekly.remove_old_snapshots() snaps = self.bm_with_label_weekly._conn.get_all_snapshots() end_snapshot = filter(lambda x: x.status == 'completed', snaps) assert len(init_snapshot) == 4 assert len(end_snapshot) == 3
def run(): parser = argparse.ArgumentParser( description= 'Loops through all EBS volumes, and snapshots them, then loops through all snapshots, and removes the oldest ones.' ) parser.add_argument( '--region', metavar='REGION', help= 'the region to loop through and snapshot (default is current region of EC2 instance this is running on). E.g. us-east-1' ) parser.add_argument( '--max-snapshots-per-volume', metavar='SNAPSHOTS', default=3, type=int, help= 'the maximum number of snapshots to keep per EBS volume. The oldest snapshots will be deleted. Default: 3' ) parser.add_argument( '--snapshot-only', action='store_true', default=False, help='Only snapshot EBS volumes, do not remove old snapshots') parser.add_argument( '--remove-only', action='store_true', default=False, help='Only remove old snapshots, do not create new snapshots') parser.add_argument('--verbose', '-v', action='count', help='enable verbose output (-vvv for more)') parser.add_argument('--version', action='version', version='%(prog)s ' + __version__, help='display version number and exit') args = parser.parse_args() Logging().configure(args.verbose) log.debug("CLI parse args: %s", args) if args.region: region = args.region else: # If no region was specified, assume this is running on an EC2 instance # and work out what region it is in log.debug("Figure out which region I am running in...") instance_metadata = get_instance_metadata(timeout=5) log.debug('Instance meta-data: %s', instance_metadata) if not instance_metadata: _fail( 'Could not determine region. This script is either not running on an EC2 instance (in which case you should use the --region option), or the meta-data service is down' ) region = instance_metadata['placement']['availability-zone'][:-1] log.debug("Running in region: %s", region) try: monkey = BackupMonkey(region, args.max_snapshots_per_volume) if not args.remove_only: monkey.snapshot_volumes() if not args.snapshot_only: monkey.remove_old_snapshots() except BackupMonkeyException as e: _fail(e.message) log.info('Backup Monkey completed successfully!') sys.exit(0)
def setUp(self, mock): self.backup_monkey = BackupMonkey('us-west-2', 3, [], None, None, None, 0)
class TagsTest(TestCase): @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def setUp(self, mock): self.backup_monkey = BackupMonkey('us-west-2', 3, [], None, None, None, 0) @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_instance(self, mock): assert isinstance(self.backup_monkey.get_connection(), MockEC2Connection) == True assert self.backup_monkey.get_volumes_to_snapshot() == volumes @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_no_tag(self, mock): ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 6 assert ret == volumes @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag(self, mock): self.backup_monkey._tags = tag ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 2 assert ret == [match_tag, match_tag_multiple] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag_or(self, mock): self.backup_monkey._tags = tag_or ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 2 assert ret == [match_tag_or_1, match_tag_or_2] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag_multiple(self, mock): self.backup_monkey._tags = tag_multiple ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 2 assert ret == [match_tag, match_tag_multiple] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag_reverse_tags(self, mock): self.backup_monkey._tags = tag self.backup_monkey._reverse_tags = True ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 4 assert ret == [a, match_tag_or_1, b, match_tag_or_2] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag_or_reverse_tags(self, mock): self.backup_monkey._tags = tag_or self.backup_monkey._reverse_tags = True ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 4 assert ret == [a, match_tag, b, match_tag_multiple] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_tag_multiple_reverse_tags(self, mock): self.backup_monkey._tags = tag_multiple self.backup_monkey._reverse_tags = True ret = self.backup_monkey.get_volumes_to_snapshot() assert len(ret) == 4 assert ret == [a, match_tag_or_1, b, match_tag_or_2] @mock.patch('backup_monkey.core.BackupMonkey.get_connection', side_effect=mock_get_connection) def test_remove_reserved_tags(self, mock): volume_tags = { 'a': 'a', 'b': 'b', 'c': 'c', 'aws:a': 'aws:a', 'aws:b': 'aws:b' } ret = self.backup_monkey.remove_reserved_tags(volume_tags) assert len(ret) == 3 assert ret == { 'a': 'a', 'b': 'b', 'c': 'c' }
def run(): parser = argparse.ArgumentParser( description= 'Loops through all EBS volumes, and snapshots them, then loops through all snapshots, and removes the oldest ones.' ) parser.add_argument( '--region', metavar='REGION', help= 'the region to loop through and snapshot (default is current region of EC2 instance this is running on). E.g. us-east-1' ) parser.add_argument( '--max-snapshots-per-volume', metavar='SNAPSHOTS', default=3, type=int, help= 'the maximum number of snapshots to keep per EBS volume. The oldest snapshots will be deleted. Default: 3' ) parser.add_argument( '--snapshot-only', action='store_true', default=False, help='Only snapshot EBS volumes, do not remove old snapshots') parser.add_argument( '--remove-only', action='store_true', default=False, help='Only remove old snapshots, do not create new snapshots') parser.add_argument('--verbose', '-v', action='count', help='enable verbose output (-vvv for more)') parser.add_argument('--version', action='version', version='%(prog)s ' + __version__, help='display version number and exit') parser.add_argument( '--tags', nargs="+", help= 'Only snapshot instances that match passed in tags. E.g. --tag Name:foo will snapshot all instances with a tag `Name` and value is `foo`' ) parser.add_argument( '--reverse-tags', action='store_true', default=False, help= 'Do a reverse match on the passed in tags. E.g. --tag Name:foo --reverse-tags will snapshot all instances that do not have a `Name` tag with the value `foo`' ) parser.add_argument( '--label', action='store', help= 'Only snapshot instances that match passed in label are created or deleted. Default: None. Selected all snapshot. You have the posibility of create a different strategies for daily, weekly and monthly for example. Label daily won\'t deleted label weekly' ) parser.add_argument( '--cross-account-number', action='store', help= 'Do a cross-account snapshot (this is the account number to do snapshots on). NOTE: This requires that you pass in the --cross-account-role parameter. E.g. --cross-account-number 111111111111 --cross-account-role Snapshot' ) parser.add_argument( '--cross-account-role', action='store', help= 'The name of the role that backup-monkey will assume when doing a cross-account snapshot. E.g. --cross-account-role Snapshot' ) args = parser.parse_args() if args.cross_account_number and not args.cross_account_role: parser.error( 'The --cross-account-role parameter is required if you specify --cross-account-number (doing a cross-account snapshot)' ) if args.cross_account_role and not args.cross_account_number: parser.error( 'The --cross-account-number parameter is required if you specify --cross-account-role (doing a cross-account snapshot)' ) if args.reverse_tags and not args.tags: parser.error( 'The --tags parameter is required if you specify --reverse-tags (doing a blacklist filter)' ) if args.label and len(args.label) > LIMIT_LABEL: parser.error('The --label parameter lenght should be less than 32') Logging().configure(args.verbose) log.debug("CLI parse args: %s", args) if args.region: region = args.region else: # If no region was specified, assume this is running on an EC2 instance # and work out what region it is in log.debug("Figure out which region I am running in...") instance_metadata = get_instance_metadata(timeout=5) log.debug('Instance meta-data: %s', instance_metadata) if not instance_metadata: _fail( 'Could not determine region. This script is either not running on an EC2 instance (in which case you should use the --region option), or the meta-data service is down' ) region = instance_metadata['placement']['availability-zone'][:-1] log.debug("Running in region: %s", region) try: monkey = BackupMonkey(region, args.max_snapshots_per_volume, args.tags, args.reverse_tags, args.label, args.cross_account_number, args.cross_account_role) if not args.remove_only: monkey.snapshot_volumes() if not args.snapshot_only: monkey.remove_old_snapshots() except BackupMonkeyException as e: _fail(e.message) log.info('Backup Monkey completed successfully!') sys.exit(0)
def run(): parser = argparse.ArgumentParser(description='Loops through all EBS volumes, and snapshots them, then loops through all snapshots, and removes the oldest ones.') parser.add_argument('--region', metavar='REGION', help='the region to loop through and snapshot (default is current region of EC2 instance this is running on). E.g. us-east-1') parser.add_argument('--max-snapshots-per-volume', metavar='SNAPSHOTS', default=3, type=int, help='the maximum number of snapshots to keep per EBS volume. The oldest snapshots will be deleted. Default: 3') parser.add_argument('--snapshot-only', action='store_true', default=False, help='Only snapshot EBS volumes, do not remove old snapshots') parser.add_argument('--remove-only', action='store_true', default=False, help='Only remove old snapshots, do not create new snapshots') parser.add_argument('--snapshot-prefix', action='store', default="BACKUP_MONKEY", help='Created snapshots will contain this prefix. Only considers snapshots for removal that start with this prefix. Default: BACKUP_MONKEY') parser.add_argument('--verbose', '-v', action='count', help='enable verbose output (-vvv for more)') parser.add_argument('--version', action='version', version='%(prog)s ' + __version__, help='display version number and exit') parser.add_argument('--tags', nargs="+", help='Only snapshot instances that match passed in tags. E.g. --tag Name:foo will snapshot all instances with a tag `Name` and value is `foo`') parser.add_argument('--reverse-tags', action='store_true', default=False, help='Do a reverse match on the passed in tags. E.g. --tag Name:foo --reverse-tags will snapshot all instances that do not have a `Name` tag with the value `foo`') parser.add_argument('--label', action='store', help='Only snapshot instances that match passed in label are created or deleted. Default: None. Selected all snapshot. You have the posibility of create a different strategies for daily, weekly and monthly for example. Label daily won\'t deleted label weekly') parser.add_argument('--cross-account-number', action='store', help='Do a cross-account snapshot (this is the account number to do snapshots on). NOTE: This requires that you pass in the --cross-account-role parameter. E.g. --cross-account-number 111111111111 --cross-account-role Snapshot') parser.add_argument('--cross-account-role', action='store', help='The name of the role that backup-monkey will assume when doing a cross-account snapshot. E.g. --cross-account-role Snapshot') parser.add_argument('--path-to-graffiti-config', action='store', help='backup-monkey can tag all created snapshots by using graffiti-monkey, if this is desired provide the absolute path to the graffiti config') args = parser.parse_args() if args.cross_account_number and not args.cross_account_role: parser.error('The --cross-account-role parameter is required if you specify --cross-account-number (doing a cross-account snapshot)') if args.cross_account_role and not args.cross_account_number: parser.error('The --cross-account-number parameter is required if you specify --cross-account-role (doing a cross-account snapshot)') if args.reverse_tags and not args.tags: parser.error('The --tags parameter is required if you specify --reverse-tags (doing a blacklist filter)') if args.label and len(args.label) > LIMIT_LABEL: parser.error('The --label parameter lenght should be less than 32') Logging().configure(args.verbose) log.debug("CLI parse args: %s", args) if args.region: region = args.region else: # If no region was specified, assume this is running on an EC2 instance # and work out what region it is in log.debug("Figure out which region I am running in...") instance_metadata = get_instance_metadata(timeout=5) log.debug('Instance meta-data: %s', instance_metadata) if not instance_metadata: _fail('Could not determine region. This script is either not running on an EC2 instance (in which case you should use the --region option), or the meta-data service is down') region = instance_metadata['placement']['availability-zone'][:-1] log.debug("Running in region: %s", region) try: monkey = BackupMonkey(region, args.max_snapshots_per_volume, args.tags, args.reverse_tags, args.label, args.cross_account_number, args.cross_account_role, args.path_to_graffiti_config, args.snapshot_prefix) if not args.remove_only: monkey.snapshot_volumes() if not args.snapshot_only: monkey.remove_old_snapshots() except BackupMonkeyException as e: _fail(e.message) log.info('Backup Monkey completed successfully!') sys.exit(0)
def setUp(self, mock): self.bm = BackupMonkey('us-west-2', 1, [], None, None, None, None) self.bm_with_label_daily = BackupMonkey('us-west-2', 1, [], None, 'daily', None, None) self.bm_with_label_weekly = BackupMonkey('us-west-2', 1, [], None, 'weekly', None, None)