Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Resource delete
  • Loading branch information
tjprescott committed Dec 4, 2018
commit d5baa30cdc9ac439b83ec69029cb659ff5a4a070
3 changes: 3 additions & 0 deletions src/azdev/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def operation_group(name):
g.command('list', 'list_extensions')
g.command('update-index', 'update_extension_index')

with CommandGroup(self, 'group', operation_group('resource')) as g:
g.command('delete', 'delete_groups')

# TODO: implement
# with CommandGroup(self, operation_group('help')) as g:
# g.command('generate', 'generate_help_xml')
Expand Down
8 changes: 8 additions & 0 deletions src/azdev/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,11 @@
helps['extension update-index'] = """
short-summary: Update the extensions index.json from a built WHL file.
"""

helps['group delete'] = """
short-summary: Delete several resource groups with filters. Useful for cleaning up test resources.
long-summary: >
Can filter either by key tags used by the CLI infrastructure, or by name prefix. If name prefix
is used, the tag filters will be ignored. This command doesn't guarantee the resource group will
be deleted.
"""
2 changes: 1 addition & 1 deletion src/azdev/operations/extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def update_extension_index(extension):
# Extract the extension name
try:
extension_name = re.findall(NAME_REGEX, extension)[0]
extension_name = extension_name.replace('_', '-')
extension_name = extension_name.replace('_', '-')az
except IndexError:
raise ValueError('unable to parse extension name')

Expand Down
81 changes: 81 additions & 0 deletions src/azdev/operations/resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -----------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -----------------------------------------------------------------------------

import json

from knack.log import get_logger
from knack.prompting import prompt_y_n
from knack.util import CLIError

from azdev.utilities import (
cmd as run_cmd, heading, subheading, display)

logger = get_logger(__name__)


class Data(object):
def __init__(self, **kw):
self.__dict__.update(kw)
if 'properties' in self.__dict__:
self.__dict__.update(self.properties)
del self.properties


def delete_groups(cmd, prefixes=None, older_than=6, product='azurecli', cause='automation', yes=False):
from datetime import datetime, timedelta

groups = json.loads(run_cmd('az group list -ojson').result)
groups_to_delete = []

def _filter_by_tags():
for group in groups:
group = Data(**group)

if not group.tags:
continue

tags = Data(**group.tags)
try:
date_tag = datetime.strptime(tags.date, '%Y-%m-%dT%H:%M:%SZ')
curr_time = datetime.utcnow()
if tags.product == product and tags.cause == cause and (curr_time - date_tag <= timedelta(hours=older_than + 1)):
groups_to_delete.append(group.name)
except AttributeError:
continue

def _filter_by_prefix():
for group in groups:
group = Data(**group)

for prefix in prefixes:
if group.name.startswith(prefix):
groups_to_delete.append(group.name)

def _delete():
for group in groups_to_delete:
run_cmd('az group delete -g {} -y --no-wait'.format(group), message=True)

if prefixes:
logger.info('Filter by prefix')
_filter_by_prefix()
else:
logger.info('Filter by tags')
_filter_by_tags

if not groups_to_delete:
raise CLIError('No groups meet the criteria to delete.')

if yes:
_delete()
else:
subheading('Groups to Delete')
for group in groups_to_delete:
display('\t{}'.format(group))

if prompt_y_n('Delete {} resource groups?'.format(len(groups_to_delete)), 'y'):
_delete()
else:
raise CLIError('Command cancelled.')
7 changes: 7 additions & 0 deletions src/azdev/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ def load_arguments(self, command):

with ArgumentsContext(self, 'extension update-index') as c:
c.positional('extension', metavar='URL', help='URL to an extension WHL file.')

with ArgumentsContext(self, 'group delete') as c:
c.argument('product', help='Value for tag `product` to mark for deletion.', arg_group='Tag')
c.argument('older_than', type=int, help='Minimum age (in hours) for tag `date` to mark for deletion.', arg_group='Tag')
c.argument('cause', help='Value for tag `cause` to mark for deletion.', arg_group='Tag')
c.argument('yes', options_list=['--yes', '-y'], help='Do not prompt.')
c.argument('prefixes', options_list=['--prefixes', '-p'], nargs='+', help='Space-separated list of prefixes to filter by.')