diff --git a/az b/az old mode 100755 new mode 100644 diff --git a/azure-cli.pyproj b/azure-cli.pyproj index 0353d43024a..28a4caa8398 100644 --- a/azure-cli.pyproj +++ b/azure-cli.pyproj @@ -33,15 +33,10 @@ - - - - Code - @@ -62,8 +57,6 @@ - - @@ -78,12 +71,6 @@ X86 - - - - - - \ No newline at end of file diff --git a/src/azure/cli/_argparse.py b/src/azure/cli/_argparse.py index c49c2136196..def620bc29a 100644 --- a/src/azure/cli/_argparse.py +++ b/src/azure/cli/_argparse.py @@ -112,7 +112,7 @@ def add_command(self, m['$args'] = [] m['$kwargs'] = kw = {} m['$argdoc'] = ad = [] - for spec, desc, req in args or []: + for spec, desc, req, target in args or []: if not any(spec.startswith(p) for p in ARG_PREFIXES): m['$args'].append(spec.strip('<> ')) ad.append((spec, desc, req)) @@ -123,7 +123,8 @@ def add_command(self, v = True else: v = aliases.pop().strip('<> ') - target, _ = _read_arg(aliases[0]) + if not target: + target, _ = _read_arg(aliases[0]) kw.update({_read_arg(a)[0]: (target, v, req, aliases) for a in aliases}) ad.append(('/'.join(aliases), desc, req)) diff --git a/src/azure/cli/commands/__init__.py b/src/azure/cli/commands/__init__.py index 23a6a8c9057..fbb05927ce1 100644 --- a/src/azure/cli/commands/__init__.py +++ b/src/azure/cli/commands/__init__.py @@ -28,10 +28,10 @@ def add_description(handler): return handler return add_description -def option(spec, description_text=None, required=False): +def option(spec, description_text=None, required=False, target=None): def add_option(handler): _COMMANDS.setdefault(handler, {}).setdefault('args', []) \ - .append((spec, description_text, required)) + .append((spec, description_text, required, target)) logger.debug('Added option "%s" to %s', spec, handler) return handler return add_option diff --git a/src/azure/cli/commands/_auto_command.py b/src/azure/cli/commands/_auto_command.py index 821aa4d1fe6..472b8215d95 100644 --- a/src/azure/cli/commands/_auto_command.py +++ b/src/azure/cli/commands/_auto_command.py @@ -7,6 +7,14 @@ from azure.cli._argparse import IncorrectUsageError from ..commands import command, description, option + +EXCLUDED_PARAMS = frozenset(['self', 'raw', 'custom_headers', 'operation_config']) +GLOBALPARAMALIASES = { + 'resource_group_name': '--resourcegroup --rg ' +} + + + class LongRunningOperation(object): #pylint: disable=too-few-public-methods progress_file = sys.stderr @@ -41,13 +49,24 @@ def _decorate_command(name, func): def _decorate_description(desc, func): return description(desc)(func) -def _decorate_option(spec, descr, func): - return option(spec, descr)(func) +def _decorate_option(spec, descr, target, func): + return option(spec, descr, target=target)(func) + +def _get_member(obj, path): + """Recursively walk down the dot-separated path + to get child item. -def _make_func(client_factory, member_name, return_type_or_func, unbound_func): + Ex. a.b.c would get the property 'c' of property 'b' of the + object a + """ + for segment in path.split('.'): + obj = getattr(obj, segment) + return obj + +def _make_func(client_factory, member_path, return_type_or_func, unbound_func): def call_client(args, unexpected): #pylint: disable=unused-argument client = client_factory() - ops_instance = getattr(client, member_name) + ops_instance = _get_member(client, member_path) try: result = unbound_func(ops_instance, **args) if not return_type_or_func: @@ -65,7 +84,6 @@ def call_client(args, unexpected): #pylint: disable=unused-argument message = getattr(client_exception, 'message', client_exception) print(message, file=sys.stderr) - return call_client def _option_description(operation, arg): @@ -76,13 +94,12 @@ def _option_description(operation, arg): return ' '.join(l.split(':')[-1] for l in inspect.getdoc(operation).splitlines() if l.startswith(':param') and arg + ':' in l) -EXCLUDED_PARAMS = frozenset(['self', 'raw', 'custom_headers', 'operation_config']) - -def build_operation(package_name, resource_type, member_name, client_type, operations): +def build_operation(command_name, member_path, client_type, operations, #pylint: disable=dangerous-default-value + paramaliases=GLOBALPARAMALIASES): for operation, return_type_name in operations: opname = operation.__name__.replace('_', '-') - func = _make_func(client_type, member_name, return_type_name, operation) - func = _decorate_command(' '.join([package_name, resource_type, opname]), func) + func = _make_func(client_type, member_path, return_type_name, operation) + func = _decorate_command(' '.join([command_name, opname]), func) args = [] try: @@ -94,5 +111,6 @@ def build_operation(package_name, resource_type, member_name, client_type, opera args = sig.args for arg in [a for a in args if not a in EXCLUDED_PARAMS]: - spec = '--%s <%s>' % (arg, arg) - func = _decorate_option(spec, _option_description(operation, arg), func=func) + spec = paramaliases.get(arg, '--%s <%s>' % (arg, arg)) + func = _decorate_option(spec, _option_description(operation, arg), + target=arg, func=func) diff --git a/src/azure/cli/commands/network.py b/src/azure/cli/commands/network.py index ee2caa89710..3dbf7798f56 100644 --- a/src/azure/cli/commands/network.py +++ b/src/azure/cli/commands/network.py @@ -21,16 +21,21 @@ VirtualNetworksOperations) from ._command_creation import get_mgmt_service_client -from ..commands._auto_command import build_operation, LongRunningOperation +from ..commands._auto_command import build_operation, LongRunningOperation, GLOBALPARAMALIASES from ..commands import command, description, option def _network_client_factory(): return get_mgmt_service_client(NetworkManagementClient, NetworkManagementClientConfiguration) +PARAMALIASES = GLOBALPARAMALIASES.copy() +PARAMALIASES.update({ + 'virtual_network_name': '--name ', + 'load_balancer_name': '--name ' + }) + # pylint: disable=line-too-long # Application gateways -build_operation("network", - "appgateway", +build_operation("network appgateway", "application_gateways", _network_client_factory, [ @@ -40,33 +45,33 @@ def _network_client_factory(): (ApplicationGatewaysOperations.list_all, '[ApplicationGateway]'), (ApplicationGatewaysOperations.start, LongRunningOperation(L('Starting application gateway'), L('Application gateway started'))), (ApplicationGatewaysOperations.stop, LongRunningOperation(L('Stopping application gateway'), L('Application gateway stopped'))), - ]) + ], + PARAMALIASES) # ExpressRouteCircuitAuthorizationsOperations -build_operation("network", - "expressroutecircuitauth", +build_operation("network expressroutecircuitauth", "express_route_circuit_authorizations", _network_client_factory, [ (ExpressRouteCircuitAuthorizationsOperations.delete, LongRunningOperation(L('Deleting express route authorization'), L('Express route authorization deleted'))), (ExpressRouteCircuitAuthorizationsOperations.get, 'ExpressRouteCircuitAuthorization'), (ExpressRouteCircuitAuthorizationsOperations.list, '[ExpressRouteCircuitAuthorization]'), - ]) + ], + PARAMALIASES) # ExpressRouteCircuitPeeringsOperations -build_operation("network", - "expressroutecircuitpeering", +build_operation("network expressroutecircuitpeering", "express_route_circuit_peerings", _network_client_factory, [ (ExpressRouteCircuitPeeringsOperations.delete, LongRunningOperation(L('Deleting express route circuit peering'), L('Express route circuit peering deleted'))), (ExpressRouteCircuitPeeringsOperations.get, 'ExpressRouteCircuitPeering'), (ExpressRouteCircuitPeeringsOperations.list, '[ExpressRouteCircuitPeering]'), - ]) + ], + PARAMALIASES) # ExpressRouteCircuitsOperations -build_operation("network", - "expressroutecircuit", +build_operation("network expressroutecircuit", "express_route_circuits", _network_client_factory, [ @@ -77,20 +82,20 @@ def _network_client_factory(): (ExpressRouteCircuitsOperations.list_stats, '[ExpressRouteCircuitStats]'), (ExpressRouteCircuitsOperations.list, '[ExpressRouteCircuit]'), (ExpressRouteCircuitsOperations.list_all, '[ExpressRouteCircuit]'), - ]) + ], + PARAMALIASES) # ExpressRouteServiceProvidersOperations -build_operation("network", - "expressroutesp", +build_operation("network expressroutesp", "express_route_service_providers", _network_client_factory, [ (ExpressRouteServiceProvidersOperations.list, '[ExpressRouteServiceProvider]'), - ]) + ], + PARAMALIASES) # LoadBalancersOperations -build_operation("network", - "lb", +build_operation("network lb", "load_balancers", _network_client_factory, [ @@ -98,23 +103,23 @@ def _network_client_factory(): (LoadBalancersOperations.get, 'LoadBalancer'), (LoadBalancersOperations.list_all, '[LoadBalancer]'), (LoadBalancersOperations.list, '[LoadBalancer]'), - ]) + ], + PARAMALIASES) # LocalNetworkGatewaysOperations -build_operation("network", - "localgateways", +build_operation("network localgateways", "local_network_gateways", _network_client_factory, [ (LocalNetworkGatewaysOperations.get, 'LocalNetworkGateway'), (LocalNetworkGatewaysOperations.delete, LongRunningOperation(L('Deleting local network gateway'), L('Local network gateway deleted'))), (LocalNetworkGatewaysOperations.list, '[LocalNetworkGateway]'), - ]) + ], + PARAMALIASES) # NetworkInterfacesOperations -build_operation("network", - "nic", +build_operation("network nic", "network_interfaces", _network_client_factory, [ @@ -125,11 +130,11 @@ def _network_client_factory(): (NetworkInterfacesOperations.get_virtual_machine_scale_set_network_interface, 'NetworkInterface'), (NetworkInterfacesOperations.list_all, '[NetworkInterface]'), (NetworkInterfacesOperations.list, '[NetworkInterface]'), - ]) + ], + PARAMALIASES) # NetworkSecurityGroupsOperations -build_operation("network", - "securitygroup", +build_operation("network securitygroup", "network_security_groups", _network_client_factory, [ @@ -137,11 +142,11 @@ def _network_client_factory(): (NetworkSecurityGroupsOperations.delete, 'NetworkSecurityGroup'), (NetworkSecurityGroupsOperations.list_all, '[NetworkSecurityGroup]'), (NetworkSecurityGroupsOperations.list, '[NetworkSecurityGroup]'), - ]) + ], + PARAMALIASES) # PublicIPAddressesOperations -build_operation("network", - "publicipaddress", +build_operation("network publicipaddress", "public_ip_addresses", _network_client_factory, [ @@ -149,11 +154,11 @@ def _network_client_factory(): (PublicIPAddressesOperations.get, 'PublicIPAddress'), (PublicIPAddressesOperations.list_all, '[PublicIPAddress]'), (PublicIPAddressesOperations.list, '[PublicIPAddress]'), - ]) + ], + PARAMALIASES) # RouteTablesOperations -build_operation("network", - "routetable", +build_operation("network routetable", "route_tables", _network_client_factory, [ @@ -161,53 +166,53 @@ def _network_client_factory(): (RouteTablesOperations.get, 'RouteTable'), (RouteTablesOperations.list, '[RouteTable]'), (RouteTablesOperations.list_all, '[RouteTable]'), - ]) + ], + PARAMALIASES) # RoutesOperations -build_operation("network", - "routeoperation", +build_operation("network routeoperation", "routes", _network_client_factory, [ (RoutesOperations.delete, LongRunningOperation(L('Deleting route'), L('Route deleted'))), (RoutesOperations.get, 'Route'), (RoutesOperations.list, '[Route]'), - ]) + ], + PARAMALIASES) # SecurityRulesOperations -build_operation("network", - "securityrules", +build_operation("network securityrules", "security_rules", _network_client_factory, [ (SecurityRulesOperations.delete, LongRunningOperation(L('Deleting security rule'), L('Security rule deleted'))), (SecurityRulesOperations.get, 'SecurityRule'), (SecurityRulesOperations.list, '[SecurityRule]'), - ]) + ], + PARAMALIASES) # SubnetsOperations -build_operation("network", - "subnet", +build_operation("network subnet", "subnets", _network_client_factory, [ (SubnetsOperations.delete, LongRunningOperation(L('Deleting subnet'), L('Subnet deleted'))), (SubnetsOperations.get, 'Subnet'), (SubnetsOperations.list, '[Subnet]'), - ]) + ], + PARAMALIASES) # UsagesOperations -build_operation("network", - "usage", +build_operation("network usage", "usages", _network_client_factory, [ (UsagesOperations.list, '[Usage]'), - ]) + ], + PARAMALIASES) # VirtualNetworkGatewayConnectionsOperations -build_operation("network", - "vnetgatewayconnection", +build_operation("network vnetgatewayconnection", "virtual_network_gateway_connections", _network_client_factory, [ @@ -217,11 +222,11 @@ def _network_client_factory(): (VirtualNetworkGatewayConnectionsOperations.list, '[VirtualNetworkGatewayConnection]'), (VirtualNetworkGatewayConnectionsOperations.reset_shared_key, 'ConnectionResetSharedKey'), (VirtualNetworkGatewayConnectionsOperations.set_shared_key, 'ConnectionSharedKey'), - ]) + ], + PARAMALIASES) # VirtualNetworkGatewaysOperations -build_operation("network", - "vnetgateway", +build_operation("network vnetgateway", "virtual_network_gateways", _network_client_factory, [ @@ -229,11 +234,11 @@ def _network_client_factory(): (VirtualNetworkGatewaysOperations.get, 'VirtualNetworkGateway'), (VirtualNetworkGatewaysOperations.list, '[VirtualNetworkGateway]'), (VirtualNetworkGatewaysOperations.reset, 'VirtualNetworkGateway'), - ]) + ], + PARAMALIASES) # VirtualNetworksOperations -build_operation("network", - "vnet", +build_operation("network vnet", "virtual_networks", _network_client_factory, [ @@ -241,7 +246,8 @@ def _network_client_factory(): (VirtualNetworksOperations.get, 'VirtualNetwork'), (VirtualNetworksOperations.list, '[VirtualNetwork]'), (VirtualNetworksOperations.list_all, '[VirtualNetwork]'), - ]) + ], + PARAMALIASES) @command('network vnet create') @description(L('Create or update a virtual network (VNet)')) diff --git a/src/azure/cli/commands/vm.py b/src/azure/cli/commands/vm.py index bdf54dff463..3dc5ca1a756 100644 --- a/src/azure/cli/commands/vm.py +++ b/src/azure/cli/commands/vm.py @@ -21,8 +21,7 @@ def _compute_client_factory(): VirtualMachineExtension._validation['location']['required'] = False # pylint: disable=protected-access # pylint: disable=line-too-long -build_operation("vm", - "availabilityset", +build_operation("vm availabilityset", "availability_sets", _compute_client_factory, [ @@ -33,8 +32,7 @@ def _compute_client_factory(): ]) -build_operation("vm", - "machineextensionimages", +build_operation("vm machineextensionimage", "virtual_machine_extension_images", _compute_client_factory, [ @@ -43,8 +41,7 @@ def _compute_client_factory(): (VirtualMachineExtensionImagesOperations.list_versions, '[VirtualMachineImageResource]'), ]) -build_operation("vm", - "extensions", +build_operation("vm extension", "virtual_machine_extensions", _compute_client_factory, [ @@ -52,8 +49,7 @@ def _compute_client_factory(): (VirtualMachineExtensionsOperations.get, 'VirtualMachineExtension'), ]) -build_operation("vm", - "image", +build_operation("vm image", "virtual_machine_images", _compute_client_factory, [ @@ -64,16 +60,14 @@ def _compute_client_factory(): (VirtualMachineImagesOperations.list_skus, '[VirtualMachineImageResource]'), ]) -build_operation("vm", - "usage", +build_operation("vm usage", "usage", _compute_client_factory, [ (UsageOperations.list, '[Usage]'), ]) -build_operation("vm", - "size", +build_operation("vm size", "virtual_machine_sizes", _compute_client_factory, [ @@ -81,7 +75,6 @@ def _compute_client_factory(): ]) build_operation("vm", - "", "virtual_machines", _compute_client_factory, [ @@ -97,8 +90,7 @@ def _compute_client_factory(): (VirtualMachinesOperations.start, LongRunningOperation(L('Starting VM'), L('VM Started'))), ]) -build_operation("vm", - "scaleset", +build_operation("vm scaleset", "virtual_machine_scale_sets", _compute_client_factory, [ @@ -116,8 +108,7 @@ def _compute_client_factory(): (VirtualMachineScaleSetsOperations.update_instances, LongRunningOperation(L('Updating VM scale set instances'), L('VM scale set instances updated'))), ]) -build_operation("vm", - "vmscaleset", +build_operation("vm scalesetvm", "virtual_machine_scale_set_vms", _compute_client_factory, [ diff --git a/src/azure/cli/tests/test_argparse.py b/src/azure/cli/tests/test_argparse.py index 98c6c6623d7..6a0b8a4ec70 100644 --- a/src/azure/cli/tests/test_argparse.py +++ b/src/azure/cli/tests/test_argparse.py @@ -37,7 +37,7 @@ def set_n3(a, b): res[2] = True def test_args(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', False), ('-b ', '', False)]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', False, None), ('-b ', '', False, None)]) cmd_result = p.execute('n1 -a x'.split()) res, other = cmd_result.result @@ -77,7 +77,7 @@ def test_args(self): def test_unexpected_args(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('-a', '', False)]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('-a', '', False, None)]) cmd_result = p.execute('n1 -b=2'.split()) res, other = cmd_result.result @@ -97,7 +97,7 @@ def test_unexpected_args(self): def test_required_args(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True), ('-b ', '', False)]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True, None), ('-b ', '', False, None)]) cmd_result = p.execute('n1 -a x'.split()) res, other = cmd_result.result @@ -132,7 +132,7 @@ def test_specify_output_format(self): def test_specify_output_format(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True), ('-b ', '', False)]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True, None), ('-b ', '', False, None)]) cmd_result = p.execute('n1 -a x'.split()) self.assertEqual(cmd_result.output_format, None) @@ -156,7 +156,7 @@ def test_specify_output_format(self): def test_args_completion(self): p = ArgumentParser('test') - p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True), ('-b ', '', False)]) + p.add_command(lambda a, b: (a, b), 'n1', args=[('--arg -a', '', True, None), ('-b ', '', False, None)]) # Can't use "with StringIO() as ...", as Python2/StringIO doesn't have __exit__. io = StringIO() diff --git a/src/azure/cli/tests/test_autocommand.py b/src/azure/cli/tests/test_autocommand.py index 5aaadc4b9e9..fe6574620ab 100644 --- a/src/azure/cli/tests/test_autocommand.py +++ b/src/azure/cli/tests/test_autocommand.py @@ -40,14 +40,14 @@ def testfunc(): func = _decorate_command(command_name, testfunc) spec = '--tre ' desc = 'Kronor' - func = _decorate_option(spec, desc, func) + func = _decorate_option(spec, desc, None, func) # Verify registered_command = _COMMANDS.get(testfunc, None) self.assertIsNotNone(registered_command) self.assertEqual(registered_command['name'], command_name) self.assertEqual(len(registered_command['args']), 1) - self.assertEqual(registered_command['args'][0], (spec, desc, False)) + self.assertEqual(registered_command['args'][0], (spec, desc, False, None)) def test_load_test_commands(self): import sys @@ -57,17 +57,17 @@ def test_load_test_commands(self): # sneaky trick to avoid loading any command modules... sys.modules['azure.cli.commands.test'] = sys - command_name = 'da command with one arg and unexpected' + command_name = 'da command with one arg and unexpected with target' def testfunc(args, _): # Check that the argument passing actually works... - self.assertEqual(args['tre'], 'wombat') + self.assertEqual(args['alternatetarget'], 'wombat') return testfunc # Run test code func = _decorate_command(command_name, testfunc) spec = '--tre ' desc = 'Kronor' - func = _decorate_option(spec, desc, func) + func = _decorate_option(spec, desc, 'alternatetarget', func) p = ArgumentParser('automcommandtest') add_to_parser(p, 'test')