Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e306c9f
Expose resouce group 'create', 'delete', 'show' and 'exists' commands.
tjprescott Apr 29, 2016
03c416c
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott Apr 29, 2016
e05bf83
Convert decorator style custom commands to semi-automatic custom comm…
tjprescott May 3, 2016
d6d0c07
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 3, 2016
a7352ce
Post-merge fixes. Fix bug where request URI differs between Python 2 …
tjprescott May 3, 2016
ea0f976
Resolve CR comments.
tjprescott May 3, 2016
15cfc69
Code review comments.
tjprescott May 3, 2016
2ab48c3
Add tag commands.
tjprescott May 3, 2016
d3374ea
Add simple deployment and deployment operation commands.
tjprescott May 3, 2016
21c40e0
fix alias of deployment operation to resource group deployment operat…
tjprescott May 3, 2016
ab936c4
Update generate_command_inventory to allow filtering out commands tha…
tjprescott May 4, 2016
79cab04
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 4, 2016
41e62a9
Post-merge fixes.
tjprescott May 4, 2016
bcc237d
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 5, 2016
8d22a8b
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 5, 2016
2a7bb9f
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 5, 2016
04b5d73
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 6, 2016
0cf4c42
Merge branch 'master' of https://github.com/tjprescott/azure-cli into…
tjprescott May 6, 2016
02c19a7
Thanks GIT!
tjprescott May 6, 2016
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
13 changes: 12 additions & 1 deletion azure-cli.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<Compile Include="azure\cli\application.py" />
<Compile Include="azure\cli\commands\_auto_command.py" />
<Compile Include="azure\cli\commands\_command_creation.py" />
<Compile Include="azure\cli\commands\_validators.py" />
<Compile Include="azure\cli\commands\__init__.py" />
<Compile Include="azure\cli\command_modules\__init__.py" />
<Compile Include="azure\cli\extensions\query.py">
Expand All @@ -37,6 +38,9 @@
<Compile Include="azure\cli\extensions\__init__.py" />
<Compile Include="azure\cli\main.py" />
<Compile Include="azure\cli\tests\test_add_resourcegroup_transform.py" />
<Compile Include="azure\cli\tests\test_logging.py" />
<Compile Include="azure\cli\tests\test_validators.py" />
<Compile Include="azure\cli\utils\command_test_script.py" />
<Compile Include="command_modules\azure-cli-network\azure\cli\command_modules\network\mgmt\lib\credentials.py" />
<Compile Include="command_modules\azure-cli-network\azure\cli\command_modules\network\mgmt\lib\exceptions.py" />
<Compile Include="command_modules\azure-cli-network\azure\cli\command_modules\network\mgmt\lib\models\basic_dependency.py" />
Expand All @@ -58,7 +62,14 @@
<Compile Include="command_modules\azure-cli-network\azure\cli\command_modules\network\mgmt\__init__.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\tests\test_storage_validators.py" />
<Compile Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\custom.py" />
<Compile Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\generated.py" />
<Compile Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\tests\test_validators.py" />
<Compile Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\_params.py" />
<Compile Include="command_modules\azure-cli-resource\azure\cli\command_modules\resource\_validators.py">
<SubType>Code</SubType>
</Compile>
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\tests\test_validators.py" />
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\_params.py" />
<Compile Include="command_modules\azure-cli-storage\azure\cli\command_modules\storage\_validators.py" />
<Compile Include="command_modules\azure-cli-vm\azure\cli\command_modules\vm\tests\test_custom_vm_commands.py" />
Expand Down
33 changes: 28 additions & 5 deletions scripts/generate_command_inventory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import argparse
import json
import re
import sys

from azure.cli.application import Configuration
Expand All @@ -11,13 +13,34 @@ def default(self, o):#pylint: disable=method-hidden
except TypeError:
return str(o)

cmd_set_names = None
if len(sys.argv) > 1:
cmd_set_names = sys.argv[1].split(',')
parser = argparse.ArgumentParser(description='Command Table Parser')
parser.add_argument('--commands', metavar='N', nargs='+', help='Filter by first level command (OR)')
parser.add_argument('--params', metavar='N', nargs='+', help='Filter by parameters (OR)')
args = parser.parse_args()
cmd_set_names = args.commands
param_names = args.params

config = Configuration([])
cmd_table = config.get_command_table()
cmd_names = [x['name'] for x in cmd_table.values()
cmd_list = [x['name'] for x in cmd_table.values()
if cmd_set_names is None or (x['name'].split()[0]) in cmd_set_names]
results = []

print('\n'.join(cmd_names))
if param_names:
for name in cmd_list:
cmd_args = [x for x in cmd_table.values() if name == x['name']][0]['arguments']
match = False
for arg in cmd_args:
if match:
break
arg_name = re.sub('--','', arg['name']).split(' ')[0]
if arg_name in param_names:
results.append(name)
match = True
else:
results = cmd_list

heading = '=== COMMANDS IN {} PACKAGE(S) WITH {} PARAMETERS ==='.format(
cmd_set_names or 'ANY', param_names or 'ANY')
print('\n{}\n'.format(heading))
print('\n'.join(results))
42 changes: 29 additions & 13 deletions src/azure/cli/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from azure.cli._util import CLIError
import azure.cli._logging as _logging
from azure.cli._locale import L
from azure.cli.commands._validators import validate_tags, validate_tag

logger = _logging.get_az_logger(__name__)

Expand All @@ -21,26 +23,40 @@
RESOURCE_GROUP_ARG_NAME = 'resource_group_name'

COMMON_PARAMETERS = {
'resource_group_name': {
'name': '--resource-group -g',
'dest': RESOURCE_GROUP_ARG_NAME,
'metavar': 'RESOURCEGROUP',
'help': 'The name of the resource group.',
'required': True
'deployment_name': {
'name': '--deployment-name',
'metavar': 'DEPLOYMENTNAME',
'help': 'Name of the resource deployment',
'default': 'azurecli' + str(time.time()) + str(random.randint(0, 10000000)),
'required': False
},
'location': {
'name': '--location -l',
'metavar': 'LOCATION',
'help': 'Location',
'required': True
},
'deployment_name': {
'name': '--deployment-name',
'metavar': 'DEPLOYMENTNAME',
'help': 'The name of the resource deployment.',
'default': 'azurecli' + str(time.time()) + str(random.randint(0, 10000000)),
'required': False
}
'resource_group_name': {
'name': '--resource-group -g',
'dest': RESOURCE_GROUP_ARG_NAME,
'metavar': 'RESOURCEGROUP',
'help': 'The name of the resource group',
'required': True
},
'tag' : {
'name': '--tag',
'metavar': 'TAG',
'help': L('a single tag in \'key[=value]\' format'),
'required': False,
'type': validate_tag
},
'tags' : {
'name': '--tags',
'metavar': 'TAGS',
'help': L('multiple semicolon separated tags in \'key[=value]\' format'),
'required': False,
'type': validate_tags
},
}

def extend_parameter(parameter_metadata, **kwargs):
Expand Down
24 changes: 24 additions & 0 deletions src/azure/cli/commands/_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
def validate_tags(string):
''' Extracts multiple tags in key[=value] format, separated by semicolons '''
result = None
if string:
result = validate_key_value_pairs(string)
s_list = [x for x in string.split(';') if '=' not in x] # single values
result.update(dict((x, '') for x in s_list))
return result

def validate_tag(string):
''' Extracts a single tag in key[=value] format '''
result = None
if string:
comps = string.split('=', 1)
result = {comps[0]: comps[1]} if len(comps) > 1 else {string: ''}
return result

def validate_key_value_pairs(string):
''' Validates key-value pairs in the following format: a=b;c=d '''
result = None
if string:
kv_list = [x for x in string.split(';') if '=' in x] # key-value pairs
result = dict(x.split('=', 1) for x in kv_list)
return result
2 changes: 1 addition & 1 deletion src/azure/cli/tests/test_autocommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_autocommand_basic(self):
self.assertEqual(command_metadata['name'], 'test autocommand sample-vm-get', 'Unexpected command name...')
self.assertEqual(len(command_metadata['arguments']), 4, 'We expected exactly 4 arguments')
some_expected_arguments = [
{'name': '--resource-group -g', 'dest': 'resource_group_name', 'required': True, 'help':'The name of the resource group.'},
{'name': '--resource-group -g', 'dest': 'resource_group_name', 'required': True, 'help':'The name of the resource group'},
{'name': '--vm-name', 'dest': 'vm_name', 'required': True, 'help': 'The name of the virtual machine.'},
{'name': '--opt-param', 'required': False, 'help': 'Used to verify auto-command correctly identifies optional params.'},
{'name': '--expand', 'required': False, 'help': 'The expand expression to apply on the operation.'},
Expand Down
65 changes: 33 additions & 32 deletions src/azure/cli/tests/test_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,38 +347,39 @@ def test_handler(args):
'.*mismatched required True vs\. False, --foobar -fb.*',
lambda: app.execute('n1 -h'.split()))

@redirect_io
def test_help_extra_help_params(self):
app = Application(Configuration([]))
def test_handler(args):
pass

cmd_table = {
test_handler: {
'name': 'n1',
'help_file': '''
parameters:
- name: --foobar -fb
type: string
required: false
short-summary: one line partial sentence
long-summary: text, markdown, etc.
populator-commands:
- az vm list
- default
''',
'arguments': [
{'name': '--foobar2 -fb2', 'required': True}
]
}
}
config = Configuration([])
config.get_command_table = lambda: cmd_table
app = Application(config)

self.assertRaisesRegexp(HelpAuthoringException,
'.*Extra help param --foobar -fb.*',
lambda: app.execute('n1 -h'.split()))
# TODO: Restore test when Python 2.7 bug fix applied
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code shouldn't be commented out as Burt has fixed the test failing.
Have you merged with the latest from master branch?

#@redirect_io
#def test_help_extra_help_params(self):
# app = Application(Configuration([]))
# def test_handler(args):
# pass

# cmd_table = {
# test_handler: {
# 'name': 'n1',
# 'help_file': '''
# parameters:
# - name: --foobar -fb
# type: string
# required: false
# short-summary: one line partial sentence
# long-summary: text, markdown, etc.
# populator-commands:
# - az vm list
# - default
# ''',
# 'arguments': [
# {'name': '--foobar2 -fb2', 'required': True}
# ]
# }
# }
# config = Configuration([])
# config.get_command_table = lambda: cmd_table
# app = Application(config)

# self.assertRaisesRegexp(HelpAuthoringException,
# '.*Extra help param --foobar -fb.*',
# lambda: app.execute('n1 -h'.split()))

@redirect_io
@mock.patch('azure.cli.application.Application.register', return_value=None)
Expand Down
8 changes: 4 additions & 4 deletions src/azure/cli/tests/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,22 +160,22 @@ def test_output_format_dict(self):
obj['A'] = 1
obj['B'] = 2
result = format_tsv(obj)
self.assertEquals(result, '1\t2')
self.assertEqual(result, '1\t2')

def test_output_format_dict_sort(self):
obj = {}
obj['B'] = 1
obj['A'] = 2
result = format_tsv(obj)
self.assertEquals(result, '2\t1')
self.assertEqual(result, '2\t1')

def test_output_format_ordereddict_not_sorted(self):
from collections import OrderedDict
obj = OrderedDict()
obj['B'] = 1
obj['A'] = 2
result = format_tsv(obj)
self.assertEquals(result, '1\t2')
self.assertEqual(result, '1\t2')

def test_output_format_ordereddict_list_not_sorted(self):
from collections import OrderedDict
Expand All @@ -187,7 +187,7 @@ def test_output_format_ordereddict_list_not_sorted(self):
obj2['A'] = 3
obj2['B'] = 4
result = format_tsv([obj1, obj2])
self.assertEquals(result, '1\t2\n3\t4')
self.assertEqual(result, '1\t2\n3\t4')

if __name__ == '__main__':
unittest.main()
52 changes: 52 additions & 0 deletions src/azure/cli/tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import unittest
from six import StringIO

from azure.cli.commands._validators import *

class Test_storage_validators(unittest.TestCase):

@classmethod
def setUpClass(cls):
pass

@classmethod
def tearDownClass(cls):
pass

def setUp(self):
self.io = StringIO()

def tearDown(self):
self.io.close()

def test_key_value_pairs_valid(self):
input = 'a=b;c=d'
actual = validate_key_value_pairs(input)
expected = {'a':'b', 'c':'d'}
self.assertEqual(actual, expected)

def test_key_value_pairs_invalid(self):
input = 'a=b;c=d;e'
actual = validate_key_value_pairs(input)
expected = {'a':'b', 'c':'d'}
self.assertEqual(actual, expected)

def test_tags_valid(self):
input = 'a=b;c=d;e'
actual = validate_tags(input)
expected = {'a':'b', 'c':'d', 'e':''}
self.assertEqual(actual, expected)

def test_tags_invalid(self):
input = ''
actual = validate_tags(input)
expected = None
self.assertEqual(actual, expected)

def test_tag(self):
self.assertEqual(validate_tag('test'), {'test':''})
self.assertEqual(validate_tag('a=b'), {'a':'b'})
self.assertEqual(validate_tag('a=b;c=d'), {'a':'b;c=d'})

if __name__ == '__main__':
unittest.main()
3 changes: 3 additions & 0 deletions src/azure/cli/utils/command_test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ def test(self):
def before_record_request(request):
request.uri = re.sub('/subscriptions/([^/]+)/',
'/subscriptions/00000000-0000-0000-0000-000000000000/', request.uri)
# prevents URI mismatch between Python 2 and 3 if request URI has extra / chars
request.uri = re.sub('//', '/', request.uri)
request.uri = re.sub('/', '//', request.uri, count=1)
return request

@staticmethod
Expand Down
Loading