diff --git a/src/command_modules/azure-cli-locationbasedservices/HISTORY.rst b/src/command_modules/azure-cli-locationbasedservices/HISTORY.rst new file mode 100644 index 00000000000..97793440e77 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/HISTORY.rst @@ -0,0 +1,8 @@ +.. :changelog: + +Release History +=============== + +0.1.0 ++++++ +* Initial release \ No newline at end of file diff --git a/src/command_modules/azure-cli-locationbasedservices/MANIFEST.in b/src/command_modules/azure-cli-locationbasedservices/MANIFEST.in new file mode 100644 index 00000000000..bb37a2723da --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/MANIFEST.in @@ -0,0 +1 @@ +include *.rst diff --git a/src/command_modules/azure-cli-locationbasedservices/README.rst b/src/command_modules/azure-cli-locationbasedservices/README.rst new file mode 100644 index 00000000000..d8a4975cf63 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/README.rst @@ -0,0 +1,7 @@ +Microsoft Azure CLI 'location based services' Command Module +==================================================== + +This package is for the 'location based services' module. +i.e. 'az locationbasedservices' + + diff --git a/src/command_modules/azure-cli-locationbasedservices/__init__.py b/src/command_modules/azure-cli-locationbasedservices/__init__.py new file mode 100644 index 00000000000..34913fb394d --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/__init__.py @@ -0,0 +1,4 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/__init__.py new file mode 100644 index 00000000000..73baee1e640 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import pkg_resources +pkg_resources.declare_namespace(__name__) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/__init__.py new file mode 100644 index 00000000000..73baee1e640 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import pkg_resources +pkg_resources.declare_namespace(__name__) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/__init__.py new file mode 100644 index 00000000000..73baee1e640 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import pkg_resources +pkg_resources.declare_namespace(__name__) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/__init__.py new file mode 100644 index 00000000000..2b6b4d45e28 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/__init__.py @@ -0,0 +1,32 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from azure.cli.core import AzCommandsLoader + +import azure.cli.command_modules.locationbasedservices._help # pylint: disable=unused-import +from azure.cli.command_modules.locationbasedservices._client_factory import cf_accounts + + +class LocationBasedServicesCommandsLoader(AzCommandsLoader): + + def __init__(self, cli_ctx=None): + from azure.cli.core.commands import CliCommandType + custom_type = CliCommandType( + operations_tmpl='azure.cli.command_modules.locationbasedservices.custom#{}', + client_factory=cf_accounts) + super(LocationBasedServicesCommandsLoader, self).__init__(cli_ctx=cli_ctx, + custom_command_type=custom_type) + + def load_command_table(self, args): + from azure.cli.command_modules.locationbasedservices.commands import load_command_table + load_command_table(self, args) + return self.command_table + + def load_arguments(self, command): + from azure.cli.command_modules.locationbasedservices._params import load_arguments + load_arguments(self, command) + + +COMMAND_LOADER_CLS = LocationBasedServicesCommandsLoader diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_client_factory.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_client_factory.py new file mode 100644 index 00000000000..f2bd8b7a998 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_client_factory.py @@ -0,0 +1,14 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + + +def cf_locationbasedservices(cli_ctx, *_): + from azure.cli.core.commands.client_factory import get_mgmt_service_client + from azure.mgmt.locationbasedservices import LocationBasedServicesManagementClient + return get_mgmt_service_client(cli_ctx, LocationBasedServicesManagementClient) + + +def cf_accounts(cli_ctx, *_): + return cf_locationbasedservices(cli_ctx).accounts diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_help.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_help.py new file mode 100644 index 00000000000..3023c6583ad --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_help.py @@ -0,0 +1,62 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.help_files import helps + +helps['locationbasedservices'] = """ + type: group + short-summary: Manage Azure Location Based Services accounts. +""" + +helps['locationbasedservices account'] = """ + type: group + short-summary: Manage Azure Location Based Services accounts. +""" + +helps['locationbasedservices account keys'] = """ + type: group + short-summary: Manage Azure Location Based Services account keys. +""" + +helps['locationbasedservices account show'] = """ + type: command + short-summary: Show the details of a Location Based Services account. +""" + +helps['locationbasedservices account list'] = """ + type: command + short-summary: Show all Location Based Services accounts in a Subscription or in a Resource Group. +""" + +helps['locationbasedservices account create'] = """ + type: command + short-summary: Create a Location Based Services account. + long-summary: | + Create a Location Based Services account. A Location Based Services account holds the keys which allow access to the Location Based Services REST APIs. +""" + +helps['locationbasedservices account update'] = """ + type: command + short-summary: Update the properties of a Location Based Services account. +""" + +helps['locationbasedservices account delete'] = """ + type: command + short-summary: Delete a Location Based Services account. +""" + +helps['locationbasedservices account keys list'] = """ + type: command + short-summary: List the keys to use with the Location Based Services APIs. + long-summary: | + List the keys to use with the Location Based Services APIs. A key is used to authenticate and authorize access to the Location Based Services REST APIs. Only one key is needed at a time; two are given to provide seamless key regeneration. +""" + +helps['locationbasedservices account keys renew'] = """ + type: command + short-summary: Renew either the primary or secondary key for use with the Location Based Services APIs. + long-summary: | + Renew either the primary or secondary key for use with the Location Based Services APIs. The old key will stop working immediately. +""" diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_params.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_params.py new file mode 100644 index 00000000000..a9822c7bfdb --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/_params.py @@ -0,0 +1,54 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.arguments import CLIArgumentType + +from azure.cli.core.commands.parameters import ( + get_enum_type, + get_resource_name_completion_list, + resource_group_name_type, + tags_type) + +from azure.cli.command_modules.locationbasedservices.validators import validate_account_name +from azure.mgmt.locationbasedservices.models.location_based_services_management_client_enums import KeyType + + +def load_arguments(self, _): + # Argument Definition + locationbasedservices_name_type = CLIArgumentType(options_list=['--name', '-n'], + completer=get_resource_name_completion_list( + 'Microsoft.LocationBasedServices/accounts'), + help='The name of the Location Based Services Account', + validator=validate_account_name) + + # Parameter Registration + with self.argument_context('locationbasedservices') as c: + c.argument('resource_group_name', + arg_type=resource_group_name_type, + id_part='resource_group', + help='Resource group name') + c.argument('account_name', + id_part='name', + arg_type=locationbasedservices_name_type) + + with self.argument_context('locationbasedservices account') as c: + c.argument('sku_name', + options_list=['--sku', '-s'], + help='The name of the SKU, in standard format (such as S0).', + arg_type=get_enum_type(['S0']), + required=False) + c.argument('tags', + arg_type=tags_type) + + # Prevent --ids argument in keys with id_part=None + with self.argument_context('locationbasedservices account keys') as c: + c.argument('account_name', + id_part=None, + arg_type=locationbasedservices_name_type) + + with self.argument_context('locationbasedservices account keys renew') as c: + c.argument('key_type', + options_list=['--key'], + arg_type=get_enum_type(KeyType)) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/commands.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/commands.py new file mode 100644 index 00000000000..125925ce471 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/commands.py @@ -0,0 +1,27 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from azure.cli.core.commands import CliCommandType +from azure.cli.command_modules.locationbasedservices._client_factory import cf_accounts + + +def load_command_table(self, _): + mgmt_type = CliCommandType( + operations_tmpl='azure.mgmt.locationbasedservices.operations.accounts_operations#AccountsOperations.{}', + client_factory=cf_accounts) + + with self.command_group('locationbasedservices account', mgmt_type) as g: + g.command('show', 'get') + g.custom_command('list', 'list_accounts') + g.custom_command('create', 'create_account') + g.command('delete', 'delete') + g.generic_update_command('update', + getter_name='get', + setter_arg_name='location_based_services_account_create_parameters', + custom_func_name='generic_update_account') + + with self.command_group('locationbasedservices account keys', mgmt_type) as g: + g.command('renew', 'regenerate_keys') + g.command('list', 'list_keys') diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/custom.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/custom.py new file mode 100644 index 00000000000..1fecfc1a829 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/custom.py @@ -0,0 +1,41 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.log import get_logger + +from azure.mgmt.locationbasedservices.models import ( + LocationBasedServicesAccountCreateParameters, + Sku) + +ACCOUNT_LOCATION = 'global' + +logger = get_logger(__name__) + + +# pylint: disable=line-too-long +def create_account(client, resource_group_name, account_name, sku_name='S0', tags=None): + sku = Sku(sku_name) + lbs_account_create_params = LocationBasedServicesAccountCreateParameters(ACCOUNT_LOCATION, sku, tags) + return client.create_or_update(resource_group_name, account_name, lbs_account_create_params) + + +def list_accounts(client, resource_group_name=None): + # Retrieve accounts via subscription + if resource_group_name is None: + return client.list_by_subscription() + # Retrieve accounts via resource group + return client.list_by_resource_group(resource_group_name) + + +def generic_update_account(instance, sku_name=None, tags=None): + # Pre-populate with old instance + lbs_account_create_params = LocationBasedServicesAccountCreateParameters(ACCOUNT_LOCATION, instance.sku, + instance.tags) + # Update fields with new parameter values + if sku_name: + lbs_account_create_params.sku.name = sku_name + if tags: + lbs_account_create_params.tags = tags + return lbs_account_create_params diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/__init__.py new file mode 100644 index 00000000000..73baee1e640 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import pkg_resources +pkg_resources.declare_namespace(__name__) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/__init__.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/__init__.py new file mode 100644 index 00000000000..73baee1e640 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/__init__.py @@ -0,0 +1,6 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- +import pkg_resources +pkg_resources.declare_namespace(__name__) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/recordings/test_create_locationbasedservices_account.yaml b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/recordings/test_create_locationbasedservices_account.yaml new file mode 100644 index 00000000000..7646ea164b2 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/recordings/test_create_locationbasedservices_account.yaml @@ -0,0 +1,761 @@ +interactions: +- request: + body: '{"location": "westus", "tags": {"use": "az-test"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [group create] + Connection: [keep-alive] + Content-Length: ['50'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 resourcemanagementclient/1.2.1 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10 + response: + body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001","name":"clitest.rg000001","location":"westus","tags":{"use":"az-test"},"properties":{"provisioningState":"Succeeded"}}'} + headers: + cache-control: [no-cache] + content-length: ['328'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:22 GMT'] + expires: ['-1'] + pragma: [no-cache] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 201, message: Created} +- request: + body: '{"location": "westus", "tags": {"use": "az-test"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [group create] + Connection: [keep-alive] + Content-Length: ['50'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 resourcemanagementclient/1.2.1 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000002?api-version=2017-05-10 + response: + body: {string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002","name":"clitest.rg000002","location":"westus","tags":{"use":"az-test"},"properties":{"provisioningState":"Succeeded"}}'} + headers: + cache-control: [no-cache] + content-length: ['328'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:23 GMT'] + expires: ['-1'] + pragma: [no-cache] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 201, message: Created} +- request: + body: '{"location": "global", "sku": {"name": "S0"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account create] + Connection: [keep-alive] + Content-Length: ['45'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\": \"S0\",\r\ + \n \"tier\": \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['406'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:27 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 201, message: Created} +- request: + body: '{"location": "global", "sku": {"name": "S0"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account create] + Connection: [keep-alive] + Content-Length: ['45'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\": \"S0\",\r\ + \n \"tier\": \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['406'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:28 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account update] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\": \"S0\",\r\ + \n \"tier\": \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['406'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:29 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: 'b''b\''{"location": "global", "tags": {"key-000003": "val-000004"}, "sku": + {"name": "S0"}}\''''' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account update] + Connection: [keep-alive] + Content-Length: ['83'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"tags\": {\r\n \"key-000003\": \"\ + val-000004\"\r\n },\r\n \"sku\": {\r\n \"name\": \"S0\",\r\n \"tier\"\ + : \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['457'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:31 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account show] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"tags\": {\r\n \"key-000003\": \"\ + val-000004\"\r\n },\r\n \"sku\": {\r\n \"name\": \"S0\",\r\n \"tier\"\ + : \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['457'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:32 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account show] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"tags\": {\r\n \"key-000003\": \"\ + val-000004\"\r\n },\r\n \"sku\": {\r\n \"name\": \"S0\",\r\n \"tier\"\ + : \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['457'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:32 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": [\r\n {\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"tags\": {\r\n \"key-000003\"\ + : \"val-000004\"\r\n },\r\n \"sku\": {\r\n \"name\": \"S0\"\ + ,\r\n \"tier\": \"Standard\"\r\n }\r\n }\r\n ]\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['534'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:34 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: '{"location": "global", "sku": {"name": "S0"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account create] + Connection: [keep-alive] + Content-Length: ['45'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts/cli-000006?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts/cli-000006\"\ + ,\r\n \"name\": \"cli-000006\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\": \"S0\",\r\ + \n \"tier\": \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['406'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:36 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 201, message: Created} +- request: + body: '{"location": "global", "sku": {"name": "S0"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account create] + Connection: [keep-alive] + Content-Length: ['45'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000007?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000007\"\ + ,\r\n \"name\": \"cli-000007\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\": \"S0\",\r\ + \n \"tier\": \"Standard\"\r\n }\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['406'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:39 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 201, message: Created} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": [\r\n {\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000007\"\ + ,\r\n \"name\": \"cli-000007\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\"\ + : \"S0\",\r\n \"tier\": \"Standard\"\r\n }\r\n },\r\n {\r\ + \n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"name\": \"cli-000005\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"tags\": {\r\n \"key-000003\"\ + : \"val-000004\"\r\n },\r\n \"sku\": {\r\n \"name\": \"S0\"\ + ,\r\n \"tier\": \"Standard\"\r\n }\r\n }\r\n ]\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['983'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:40 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": [\r\n {\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts/cli-000006\"\ + ,\r\n \"name\": \"cli-000006\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\"\ + : \"S0\",\r\n \"tier\": \"Standard\"\r\n }\r\n }\r\n ]\r\n\ + }"} + headers: + cache-control: [no-cache] + content-length: ['471'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:42 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account keys list] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005/listKeys?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"primaryKey\": \"wBpB9fRVKMD32aANz2W_FlDeYm_eM0jWfDdVo3CbdqU\",\r\n\ + \ \"secondaryKey\": \"3dteq5uw_i9PyGmccxeVn_X0nObOKIvGetCp_PXKeF0\",\r\n\ + \ \"primaryKeyLastUpdated\": \"2018-03-21T01:05:26.0418034Z\",\r\n \"secondaryKeyLastUpdated\"\ + : \"2018-03-21T01:05:26.0418034Z\"\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['482'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:43 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: '{"keyType": "primary"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account keys renew] + Connection: [keep-alive] + Content-Length: ['22'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005/regenerateKey?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"primaryKey\": \"VQlHeo6BqHPGXqKuLyWP8CGWPge1OfaXtpAZLXDRqcc\",\r\n\ + \ \"secondaryKey\": \"3dteq5uw_i9PyGmccxeVn_X0nObOKIvGetCp_PXKeF0\",\r\n\ + \ \"primaryKeyLastUpdated\": \"2018-03-21T01:05:45.8319164Z\",\r\n \"secondaryKeyLastUpdated\"\ + : \"2018-03-21T01:05:26.0418034Z\"\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['482'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:45 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: '{"keyType": "secondary"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account keys renew] + Connection: [keep-alive] + Content-Length: ['24'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: POST + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005/regenerateKey?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005\"\ + ,\r\n \"primaryKey\": \"VQlHeo6BqHPGXqKuLyWP8CGWPge1OfaXtpAZLXDRqcc\",\r\n\ + \ \"secondaryKey\": \"LIfdy4wFWwFqo5jjCgMMLE2EA7Y4Kdd9QIkeniitHF0\",\r\n\ + \ \"primaryKeyLastUpdated\": \"2018-03-21T01:05:45.8319164Z\",\r\n \"secondaryKeyLastUpdated\"\ + : \"2018-03-21T01:05:47.6913121Z\"\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['482'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:47 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account delete] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000005?api-version=2017-01-01-preview + response: + body: {string: ''} + headers: + cache-control: [no-cache] + content-length: ['0'] + date: ['Wed, 21 Mar 2018 01:05:50 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": [\r\n {\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000007\"\ + ,\r\n \"name\": \"cli-000007\",\r\n \"type\": \"Microsoft.LocationBasedServices/accounts\"\ + ,\r\n \"location\": \"global\",\r\n \"sku\": {\r\n \"name\"\ + : \"S0\",\r\n \"tier\": \"Standard\"\r\n }\r\n }\r\n ]\r\n\ + }"} + headers: + cache-control: [no-cache] + content-length: ['471'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:52 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account delete] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts/cli-000006?api-version=2017-01-01-preview + response: + body: {string: ''} + headers: + cache-control: [no-cache] + content-length: ['0'] + date: ['Wed, 21 Mar 2018 01:05:54 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1198'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account delete] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts/cli-000007?api-version=2017-01-01-preview + response: + body: {string: ''} + headers: + cache-control: [no-cache] + content-length: ['0'] + date: ['Wed, 21 Mar 2018 01:05:55 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": []\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['19'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:56 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [locationbasedservices account list] + Connection: [keep-alive] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 azure-mgmt-locationbasedservices/0.1.0 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000002/providers/Microsoft.LocationBasedServices/accounts?api-version=2017-01-01-preview + response: + body: {string: "{\r\n \"value\": []\r\n}"} + headers: + cache-control: [no-cache] + content-length: ['19'] + content-type: [application/json; charset=utf-8] + date: ['Wed, 21 Mar 2018 01:05:57 GMT'] + expires: ['-1'] + pragma: [no-cache] + server: [Microsoft-HTTPAPI/2.0] + strict-transport-security: [max-age=31536000; includeSubDomains] + transfer-encoding: [chunked] + vary: [Accept-Encoding] + x-content-type-options: [nosniff] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [group delete] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 resourcemanagementclient/1.2.1 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000002?api-version=2017-05-10 + response: + body: {string: ''} + headers: + cache-control: [no-cache] + content-length: ['0'] + date: ['Wed, 21 Mar 2018 01:05:58 GMT'] + expires: ['-1'] + location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkdKR1VGWVlVTk9VRENLTE1KQ0JaN1lETzJEQ1k2WUFUTFZZUHw5RkVCNjVGNjM5OEIwRTM2LVdFU1RVUyIsImpvYkxvY2F0aW9uIjoid2VzdHVzIn0?api-version=2017-05-10'] + pragma: [no-cache] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 202, message: Accepted} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + CommandName: [group delete] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; charset=utf-8] + User-Agent: [python/3.6.4 (Windows-10-10.0.16299-SP0) requests/2.18.4 msrest/0.4.26 + msrest_azure/0.4.21 resourcemanagementclient/1.2.1 Azure-SDK-For-Python + AZURECLI/2.0.30] + accept-language: [en-US] + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2017-05-10 + response: + body: {string: ''} + headers: + cache-control: [no-cache] + content-length: ['0'] + date: ['Wed, 21 Mar 2018 01:05:59 GMT'] + expires: ['-1'] + location: ['https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/operationresults/eyJqb2JJZCI6IlJFU09VUkNFR1JPVVBERUxFVElPTkpPQi1DTElURVNUOjJFUkcyNExFMldGRFpXU0ZMVlZWUDM0UE5SSzI1UlFDVFRVTjdYQ3w4N0IyN0M1QTkzQzg2MTRCLVdFU1RVUyIsImpvYkxvY2F0aW9uIjoid2VzdHVzIn0?api-version=2017-05-10'] + pragma: [no-cache] + strict-transport-security: [max-age=31536000; includeSubDomains] + x-content-type-options: [nosniff] + x-ms-ratelimit-remaining-subscription-writes: ['1199'] + status: {code: 202, message: Accepted} +version: 1 diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_commands.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_commands.py new file mode 100644 index 00000000000..c431ac3f138 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_commands.py @@ -0,0 +1,154 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import re + +from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer +from azure.mgmt.locationbasedservices.models.location_based_services_management_client_enums import KeyType + + +class LocationBasedServicesScenarioTests(ScenarioTest): + + @ResourceGroupPreparer(key='rg') + @ResourceGroupPreparer(key='rg1') + def test_create_locationbasedservices_account(self, resource_group): + tag_key = self.create_random_name(prefix='key-', length=10) + tag_value = self.create_random_name(prefix='val-', length=10) + + self.kwargs.update({ + 'name': self.create_random_name(prefix='cli-', length=20), + 'name1': self.create_random_name(prefix='cli-', length=20), + 'name2': self.create_random_name(prefix='cli-', length=20), + 'sku': 'S0', + 'tags': tag_key + '=' + tag_value, + 'key_type_primary': KeyType.primary.value, + 'key_type_secondary': KeyType.secondary.value + }) + + # Test 'az locationbasedservices account create'. + # Test to create a LocationBasedServices account. + account = self.cmd('az locationbasedservices account create -n {name} -g {rg} --sku {sku}', + checks=[ + self.check('name', '{name}'), + self.check('resourceGroup', '{rg}'), + self.check('sku.name', '{sku}'), + self.check('tags', None) + ]).get_output_in_json() + + # Call create again, expect to get the same account. + account_duplicated = self.cmd( + 'az locationbasedservices account create -n {name} -g {rg} --sku {sku}').get_output_in_json() + self.assertEqual(account, account_duplicated) + + # Test 'az locationbasedservices account update' + # Test to add a new tag to an existing account. + self.cmd('az locationbasedservices account update -n {name} -g {rg} --sku {sku} --tags {tags}', + checks=[ + self.check('id', account['id']), + self.check('name', '{name}'), + self.check('resourceGroup', '{rg}'), + self.check('sku.name', '{sku}'), + self.check('tags', {tag_key: tag_value}) + ]) + + # Test 'az locationbasedservices account show'. + # Test to get information on LocationBasedServices account. + self.cmd('az locationbasedservices account show -n {name} -g {rg}', checks=[ + self.check('id', account['id']), + self.check('name', '{name}'), + self.check('resourceGroup', '{rg}'), + self.check('sku.name', '{sku}') + ]) + # Search by id + self.cmd('az locationbasedservices account show --ids ' + account['id'], checks=[ + self.check('id', account['id']), + self.check('name', '{name}'), + self.check('resourceGroup', '{rg}'), + self.check('sku.name', '{sku}'), + self.check('tags', {tag_key: tag_value}) + ]) + + # Test 'az locationbasedservices account list'. + # Test to list all LocationBasedServices accounts under a resource group. + self.cmd('az locationbasedservices account list -g {rg}', checks=[ + self.check('length(@)', 1), + self.check('type(@)', 'array'), + self.check('[0].id', account['id']), + self.check('[0].name', '{name}'), + self.check('[0].resourceGroup', '{rg}'), + self.check('[0].sku.name', '{sku}'), + self.check('[0].tags', {tag_key: tag_value}) + ]) + + # Create two new accounts (One in separate resource group). + self.cmd('az locationbasedservices account create -n {name1} -g {rg1} --sku {sku}') + self.cmd('az locationbasedservices account create -n {name2} -g {rg} --sku {sku}') + # Check that list command now shows two accounts in one resource group, and one in another. + self.cmd('az locationbasedservices account list -g {rg}', checks=[ + self.check('length(@)', 2), + self.check('type(@)', 'array'), + self.check("length([?name == '{name}'])", 1), + self.check("length([?name == '{name1}'])", 0), + self.check("length([?name == '{name2}'])", 1), + self.check("length([?resourceGroup == '{rg}'])", 2), + self.check("length([?resourceGroup == '{rg1}'])", 0) + ]) + self.cmd('az locationbasedservices account list -g {rg1}', checks=[ + self.check('length(@)', 1), + self.check('type(@)', 'array'), + self.check("length([?name == '{name}'])", 0), + self.check("length([?name == '{name1}'])", 1), + self.check("length([?name == '{name2}'])", 0), + self.check("length([?resourceGroup == '{rg}'])", 0), + self.check("length([?resourceGroup == '{rg1}'])", 1) + ]) + + # Test 'az locationbasedservices account key list'. + # Test to list keys for an LocationBasedServices account. + account_key_list = self.cmd('az locationbasedservices account keys list -n {name} -g {rg}', checks=[ + self.check('id', account['id']), + self.check('resourceGroup', '{rg}') + ]).get_output_in_json() + + # Retrieve primary and secondary keys. + primary_key_old = account_key_list['primaryKey'] + secondary_key_old = account_key_list['secondaryKey'] + self.assertTrue(re.match('^[a-zA-Z0-9_-]+$', primary_key_old)) + self.assertTrue(re.match('^[a-zA-Z0-9_-]+$', secondary_key_old)) + + # Test 'az locationbasedservices account key regenerate'. + # Test to change primary and secondary keys for an LocationBasedServices account. + key_regenerated = self.cmd( + 'az locationbasedservices account keys renew -n {name} -g {rg} --key {key_type_primary}', checks=[ + self.check('id', account['id']), + self.check('resourceGroup', '{rg}') + ]).get_output_in_json() + + # Only primary key was regenerated. Secondary key should remain same. + self.assertNotEqual(primary_key_old, key_regenerated['primaryKey']) + self.assertEqual(secondary_key_old, key_regenerated['secondaryKey']) + + # Save the new primary key, and regenerate the secondary key. + primary_key_old = key_regenerated['primaryKey'] + key_regenerated = self.cmd( + 'az locationbasedservices account keys renew -n {name} -g {rg} --key {key_type_secondary}') \ + .get_output_in_json() + self.assertEqual(primary_key_old, key_regenerated['primaryKey']) + self.assertNotEqual(secondary_key_old, key_regenerated['secondaryKey']) + + # Test 'az locationbasedservices account delete'. + # Test to remove an LocationBasedServices account. + self.cmd('az locationbasedservices account delete -n {name} -g {rg}', checks=self.is_empty()) + self.cmd('az locationbasedservices account list -g {rg}', checks=[ + self.check('length(@)', 1), + self.check("length([?name == '{name}'])", 0) + ]) + + # Remove the rest of LocationBasedServices accounts. + exit_code = self.cmd('az locationbasedservices account delete -n {name1} -g {rg1}').exit_code + self.assertEqual(exit_code, 0) + self.cmd('az locationbasedservices account delete -n {name2} -g {rg}') + self.cmd('az locationbasedservices account list -g {rg}', checks=self.is_empty()) + self.cmd('az locationbasedservices account list -g {rg1}', checks=self.is_empty()) diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_validators.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_validators.py new file mode 100644 index 00000000000..3ad45a052c0 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/tests/latest/test_lbs_validators.py @@ -0,0 +1,46 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import unittest + +from argparse import Namespace +from knack.util import CLIError +from azure.cli.command_modules.locationbasedservices.validators import validate_account_name, ACCOUNT_NAME_MAX_LENGTH + + +class TestValidators(unittest.TestCase): + def setUp(self): + self.namespace = Namespace() + + def _assert_invalid_account_names(self, invalid_names): + for invalid_name in invalid_names: + self.namespace.account_name = invalid_name + self.assertRaises(CLIError, lambda: validate_account_name(self.namespace)) + + def _assert_valid_account_names(self, valid_names): + for valid_name in valid_names: + self.namespace.account_name = valid_name + try: + validate_account_name(self.namespace) + except CLIError: + self.fail("validate_account_name() raised CLIError unexpectedly!") + + def test_validate_account_name_length(self): + invalid_names = ["", "a", "a" * (ACCOUNT_NAME_MAX_LENGTH + 1)] + valid_names = ["Valid-Account-Name", "aa", "a" * ACCOUNT_NAME_MAX_LENGTH] + + self._assert_invalid_account_names(invalid_names) + self._assert_valid_account_names(valid_names) + + def test_validate_account_name_regex(self): + invalid_names = ["_A", "úñícódé", "ΞΞ", "resumé", "American cheese"] + valid_names = ["Bergenost", "Cheddar_cheese", "Colby-Jack", "Cottage.cheese", "Cr34MCh3353", "montereyjack"] + + self._assert_invalid_account_names(invalid_names) + self._assert_valid_account_names(valid_names) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/validators.py b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/validators.py new file mode 100644 index 00000000000..b856452c4f5 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure/cli/command_modules/locationbasedservices/validators.py @@ -0,0 +1,26 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import re + +from knack.util import CLIError + +ACCOUNT_NAME_MIN_LENGTH = 2 +ACCOUNT_NAME_MAX_LENGTH = 64 +ACCOUNT_NAME_REGEX = re.compile("^[a-zA-Z0-9][a-zA-Z0-9_.-]*$") + + +def validate_account_name(namespace): + """ Validates account name.""" + account_name = namespace.account_name + char_len = len(account_name) + + if not ACCOUNT_NAME_MIN_LENGTH <= char_len <= ACCOUNT_NAME_MAX_LENGTH: + raise CLIError("Input account-name is invalid. Account name character length must be between 2 and 64.") + if not re.match(ACCOUNT_NAME_REGEX, account_name): + raise CLIError("Input account-name is invalid. Allowed regex: " + ACCOUNT_NAME_REGEX.pattern + + "\nFirst character must be alphanumeric." + + "\nSubsequent character(s) must be any combination of alphanumeric, underscore (_), " + + "period (.), or hyphen (-).") diff --git a/src/command_modules/azure-cli-locationbasedservices/azure_bdist_wheel.py b/src/command_modules/azure-cli-locationbasedservices/azure_bdist_wheel.py new file mode 100644 index 00000000000..3ffa5ea50a9 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/azure_bdist_wheel.py @@ -0,0 +1,533 @@ +""" +"wheel" copyright (c) 2012-2017 Daniel Holth and +contributors. + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Create a Azure wheel (.whl) distribution (a wheel is a built archive format). + +This file is a copy of the official bdist_wheel file from wheel 0.30.0a0, enhanced +of the bottom with some Microsoft extension for Azure SDK for Python + +""" + +import csv +import hashlib +import os +import subprocess +import warnings +import shutil +import json +import sys + +try: + import sysconfig +except ImportError: # pragma nocover + # Python < 2.7 + import distutils.sysconfig as sysconfig + +import pkg_resources + +safe_name = pkg_resources.safe_name +safe_version = pkg_resources.safe_version + +from shutil import rmtree +from email.generator import Generator + +from distutils.core import Command +from distutils.sysconfig import get_python_version + +from distutils import log as logger + +from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag, get_platform +from wheel.util import native, open_for_csv +from wheel.archive import archive_wheelfile +from wheel.pkginfo import read_pkg_info, write_pkg_info +from wheel.metadata import pkginfo_to_dict +from wheel import pep425tags, metadata +from wheel import __version__ as wheel_version + +def safer_name(name): + return safe_name(name).replace('-', '_') + +def safer_version(version): + return safe_version(version).replace('-', '_') + +class bdist_wheel(Command): + + description = 'create a wheel distribution' + + user_options = [('bdist-dir=', 'b', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('relative', None, + "build the archive using relative paths" + "(default: false)"), + ('owner=', 'u', + "Owner name used when creating a tar file" + " [default: current user]"), + ('group=', 'g', + "Group name used when creating a tar file" + " [default: current group]"), + ('universal', None, + "make a universal wheel" + " (default: false)"), + ('python-tag=', None, + "Python implementation compatibility tag" + " (default: py%s)" % get_impl_ver()[0]), + ] + + boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal'] + + def initialize_options(self): + self.bdist_dir = None + self.data_dir = None + self.plat_name = None + self.plat_tag = None + self.format = 'zip' + self.keep_temp = False + self.dist_dir = None + self.distinfo_dir = None + self.egginfo_dir = None + self.root_is_pure = None + self.skip_build = None + self.relative = False + self.owner = None + self.group = None + self.universal = False + self.python_tag = 'py' + get_impl_ver()[0] + self.plat_name_supplied = False + + def finalize_options(self): + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'wheel') + + self.data_dir = self.wheel_dist_name + '.data' + self.plat_name_supplied = self.plat_name is not None + + need_options = ('dist_dir', 'plat_name', 'skip_build') + + self.set_undefined_options('bdist', + *zip(need_options, need_options)) + + self.root_is_pure = not (self.distribution.has_ext_modules() + or self.distribution.has_c_libraries()) + + # Support legacy [wheel] section for setting universal + wheel = self.distribution.get_option_dict('wheel') + if 'universal' in wheel: + # please don't define this in your global configs + val = wheel['universal'][1].strip() + if val.lower() in ('1', 'true', 'yes'): + self.universal = True + + @property + def wheel_dist_name(self): + """Return distribution full name with - replaced with _""" + return '-'.join((safer_name(self.distribution.get_name()), + safer_version(self.distribution.get_version()))) + + def get_tag(self): + # bdist sets self.plat_name if unset, we should only use it for purepy + # wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + plat_name = self.plat_name or get_platform() + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647: + plat_name = 'linux_i686' + plat_name = plat_name.replace('-', '_').replace('.', '_') + + + if self.root_is_pure: + if self.universal: + impl = 'py2.py3' + else: + impl = self.python_tag + tag = (impl, 'none', plat_name) + else: + impl_name = get_abbr_impl() + impl_ver = get_impl_ver() + # PEP 3149 + abi_tag = str(get_abi_tag()).lower() + tag = (impl_name + impl_ver, abi_tag, plat_name) + supported_tags = pep425tags.get_supported( + supplied_platform=plat_name if self.plat_name_supplied else None) + # XXX switch to this alternate implementation for non-pure: + assert tag == supported_tags[0], "%s != %s" % (tag, supported_tags[0]) + return tag + + def get_archive_basename(self): + """Return archive name without extension""" + + impl_tag, abi_tag, plat_tag = self.get_tag() + + archive_basename = "%s-%s-%s-%s" % ( + self.wheel_dist_name, + impl_tag, + abi_tag, + plat_tag) + return archive_basename + + def run(self): + build_scripts = self.reinitialize_command('build_scripts') + build_scripts.executable = 'python' + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', + reinit_subcommands=True) + install.root = self.bdist_dir + install.compile = False + install.skip_build = self.skip_build + install.warn_dir = False + + # A wheel without setuptools scripts is more cross-platform. + # Use the (undocumented) `no_ep` option to setuptools' + # install_scripts command to avoid creating entry point scripts. + install_scripts = self.reinitialize_command('install_scripts') + install_scripts.no_ep = True + + # Use a custom scheme for the archive, because we have to decide + # at installation time which scheme to use. + for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'): + setattr(install, + 'install_' + key, + os.path.join(self.data_dir, key)) + + basedir_observed = '' + + if os.name == 'nt': + # win32 barfs if any of these are ''; could be '.'? + # (distutils.command.install:change_roots bug) + basedir_observed = os.path.normpath(os.path.join(self.data_dir, '..')) + self.install_libbase = self.install_lib = basedir_observed + + setattr(install, + 'install_purelib' if self.root_is_pure else 'install_platlib', + basedir_observed) + + logger.info("installing to %s", self.bdist_dir) + + self.run_command('install') + + archive_basename = self.get_archive_basename() + + pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) + if not self.relative: + archive_root = self.bdist_dir + else: + archive_root = os.path.join( + self.bdist_dir, + self._ensure_relative(install.install_base)) + + self.set_undefined_options( + 'install_egg_info', ('target', 'egginfo_dir')) + self.distinfo_dir = os.path.join(self.bdist_dir, + '%s.dist-info' % self.wheel_dist_name) + self.egg2dist(self.egginfo_dir, + self.distinfo_dir) + + self.write_wheelfile(self.distinfo_dir) + + self.write_record(self.bdist_dir, self.distinfo_dir) + + # Make the archive + if not os.path.exists(self.dist_dir): + os.makedirs(self.dist_dir) + wheel_name = archive_wheelfile(pseudoinstall_root, archive_root) + + # Sign the archive + if 'WHEEL_TOOL' in os.environ: + subprocess.call([os.environ['WHEEL_TOOL'], 'sign', wheel_name]) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_wheel', get_python_version(), wheel_name)) + + if not self.keep_temp: + if self.dry_run: + logger.info('removing %s', self.bdist_dir) + else: + rmtree(self.bdist_dir) + + def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): + from email.message import Message + msg = Message() + msg['Wheel-Version'] = '1.0' # of the spec + msg['Generator'] = generator + msg['Root-Is-Purelib'] = str(self.root_is_pure).lower() + + # Doesn't work for bdist_wininst + impl_tag, abi_tag, plat_tag = self.get_tag() + for impl in impl_tag.split('.'): + for abi in abi_tag.split('.'): + for plat in plat_tag.split('.'): + msg['Tag'] = '-'.join((impl, abi, plat)) + + wheelfile_path = os.path.join(wheelfile_base, 'WHEEL') + logger.info('creating %s', wheelfile_path) + with open(wheelfile_path, 'w') as f: + Generator(f, maxheaderlen=0).flatten(msg) + + def _ensure_relative(self, path): + # copied from dir_util, deleted + drive, path = os.path.splitdrive(path) + if path[0:1] == os.sep: + path = drive + path[1:] + return path + + def _pkginfo_to_metadata(self, egg_info_path, pkginfo_path): + return metadata.pkginfo_to_metadata(egg_info_path, pkginfo_path) + + def license_file(self): + """Return license filename from a license-file key in setup.cfg, or None.""" + metadata = self.distribution.get_option_dict('metadata') + if not 'license_file' in metadata: + return None + return metadata['license_file'][1] + + def setupcfg_requirements(self): + """Generate requirements from setup.cfg as + ('Requires-Dist', 'requirement; qualifier') tuples. From a metadata + section in setup.cfg: + + [metadata] + provides-extra = extra1 + extra2 + requires-dist = requirement; qualifier + another; qualifier2 + unqualified + + Yields + + ('Provides-Extra', 'extra1'), + ('Provides-Extra', 'extra2'), + ('Requires-Dist', 'requirement; qualifier'), + ('Requires-Dist', 'another; qualifier2'), + ('Requires-Dist', 'unqualified') + """ + metadata = self.distribution.get_option_dict('metadata') + + # our .ini parser folds - to _ in key names: + for key, title in (('provides_extra', 'Provides-Extra'), + ('requires_dist', 'Requires-Dist')): + if not key in metadata: + continue + field = metadata[key] + for line in field[1].splitlines(): + line = line.strip() + if not line: + continue + yield (title, line) + + def add_requirements(self, metadata_path): + """Add additional requirements from setup.cfg to file metadata_path""" + additional = list(self.setupcfg_requirements()) + if not additional: return + pkg_info = read_pkg_info(metadata_path) + if 'Provides-Extra' in pkg_info or 'Requires-Dist' in pkg_info: + warnings.warn('setup.cfg requirements overwrite values from setup.py') + del pkg_info['Provides-Extra'] + del pkg_info['Requires-Dist'] + for k, v in additional: + pkg_info[k] = v + write_pkg_info(metadata_path, pkg_info) + + def egg2dist(self, egginfo_path, distinfo_path): + """Convert an .egg-info directory into a .dist-info directory""" + def adios(p): + """Appropriately delete directory, file or link.""" + if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(p): + shutil.rmtree(p) + elif os.path.exists(p): + os.unlink(p) + + adios(distinfo_path) + + if not os.path.exists(egginfo_path): + # There is no egg-info. This is probably because the egg-info + # file/directory is not named matching the distribution name used + # to name the archive file. Check for this case and report + # accordingly. + import glob + pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info') + possible = glob.glob(pat) + err = "Egg metadata expected at %s but not found" % (egginfo_path,) + if possible: + alt = os.path.basename(possible[0]) + err += " (%s found - possible misnamed archive file?)" % (alt,) + + raise ValueError(err) + + if os.path.isfile(egginfo_path): + # .egg-info is a single file + pkginfo_path = egginfo_path + pkg_info = self._pkginfo_to_metadata(egginfo_path, egginfo_path) + os.mkdir(distinfo_path) + else: + # .egg-info is a directory + pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO') + pkg_info = self._pkginfo_to_metadata(egginfo_path, pkginfo_path) + + # ignore common egg metadata that is useless to wheel + shutil.copytree(egginfo_path, distinfo_path, + ignore=lambda x, y: set(('PKG-INFO', + 'requires.txt', + 'SOURCES.txt', + 'not-zip-safe',))) + + # delete dependency_links if it is only whitespace + dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt') + with open(dependency_links_path, 'r') as dependency_links_file: + dependency_links = dependency_links_file.read().strip() + if not dependency_links: + adios(dependency_links_path) + + write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info) + + # XXX deprecated. Still useful for current distribute/setuptools. + metadata_path = os.path.join(distinfo_path, 'METADATA') + self.add_requirements(metadata_path) + + # XXX intentionally a different path than the PEP. + metadata_json_path = os.path.join(distinfo_path, 'metadata.json') + pymeta = pkginfo_to_dict(metadata_path, + distribution=self.distribution) + + if 'description' in pymeta: + description_filename = 'DESCRIPTION.rst' + description_text = pymeta.pop('description') + description_path = os.path.join(distinfo_path, + description_filename) + with open(description_path, "wb") as description_file: + description_file.write(description_text.encode('utf-8')) + pymeta['extensions']['python.details']['document_names']['description'] = description_filename + + # XXX heuristically copy any LICENSE/LICENSE.txt? + license = self.license_file() + if license: + license_filename = 'LICENSE.txt' + shutil.copy(license, os.path.join(self.distinfo_dir, license_filename)) + pymeta['extensions']['python.details']['document_names']['license'] = license_filename + + with open(metadata_json_path, "w") as metadata_json: + json.dump(pymeta, metadata_json, sort_keys=True) + + adios(egginfo_path) + + def write_record(self, bdist_dir, distinfo_dir): + from wheel.util import urlsafe_b64encode + + record_path = os.path.join(distinfo_dir, 'RECORD') + record_relpath = os.path.relpath(record_path, bdist_dir) + + def walk(): + for dir, dirs, files in os.walk(bdist_dir): + dirs.sort() + for f in sorted(files): + yield os.path.join(dir, f) + + def skip(path): + """Wheel hashes every possible file.""" + return (path == record_relpath) + + with open_for_csv(record_path, 'w+') as record_file: + writer = csv.writer(record_file) + for path in walk(): + relpath = os.path.relpath(path, bdist_dir) + if skip(relpath): + hash = '' + size = '' + else: + with open(path, 'rb') as f: + data = f.read() + digest = hashlib.sha256(data).digest() + hash = 'sha256=' + native(urlsafe_b64encode(digest)) + size = len(data) + record_path = os.path.relpath( + path, bdist_dir).replace(os.path.sep, '/') + writer.writerow((record_path, hash, size)) + + +#------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +#-------------------------------------------------------------------------- + +from distutils import log as logger +import os.path + +#from wheel.bdist_wheel import bdist_wheel +class azure_bdist_wheel(bdist_wheel): + + description = "Create an Azure wheel distribution" + + user_options = bdist_wheel.user_options + \ + [('azure-namespace-package=', None, + "Name of the deepest nspkg used")] + + def initialize_options(self): + bdist_wheel.initialize_options(self) + self.azure_namespace_package = None + + def finalize_options(self): + bdist_wheel.finalize_options(self) + if self.azure_namespace_package and not self.azure_namespace_package.endswith("-nspkg"): + raise ValueError("azure_namespace_package must finish by -nspkg") + + def run(self): + if not self.distribution.install_requires: + self.distribution.install_requires = [] + self.distribution.install_requires.append( + "{}>=2.0.0".format(self.azure_namespace_package.replace('_', '-'))) + bdist_wheel.run(self) + + def write_record(self, bdist_dir, distinfo_dir): + if self.azure_namespace_package: + # Split and remove last part, assuming it's "nspkg" + subparts = self.azure_namespace_package.split('-')[0:-1] + folder_with_init = [os.path.join(*subparts[0:i+1]) for i in range(len(subparts))] + for azure_sub_package in folder_with_init: + init_file = os.path.join(bdist_dir, azure_sub_package, '__init__.py') + if os.path.isfile(init_file): + logger.info("manually remove {} while building the wheel".format(init_file)) + os.remove(init_file) + else: + raise ValueError("Unable to find {}. Are you sure of your namespace package?".format(init_file)) + bdist_wheel.write_record(self, bdist_dir, distinfo_dir) +cmdclass = { + 'bdist_wheel': azure_bdist_wheel, +} diff --git a/src/command_modules/azure-cli-locationbasedservices/setup.cfg b/src/command_modules/azure-cli-locationbasedservices/setup.cfg new file mode 100644 index 00000000000..3326c62a76e --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/setup.cfg @@ -0,0 +1,3 @@ +[bdist_wheel] +universal=1 +azure-namespace-package=azure-cli-command_modules-nspkg diff --git a/src/command_modules/azure-cli-locationbasedservices/setup.py b/src/command_modules/azure-cli-locationbasedservices/setup.py new file mode 100644 index 00000000000..5a8a3a89f39 --- /dev/null +++ b/src/command_modules/azure-cli-locationbasedservices/setup.py @@ -0,0 +1,61 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from codecs import open +from setuptools import setup + +try: + from azure_bdist_wheel import cmdclass +except ImportError: + from distutils import log as logger + logger.warn("Wheel is not available, disabling bdist_wheel hook") + cmdclass = {} + +VERSION = "0.1.0" + +# The full list of classifiers is available at +# https://pypi.python.org/pypi?%3Aaction=list_classifiers +CLASSIFIERS = [ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', +] + +DEPENDENCIES = [ + 'azure-cli-core', + 'azure-mgmt-locationbasedservices==0.1.0' +] + +with open('README.rst', 'r', encoding='utf-8') as f: + README = f.read() +with open('HISTORY.rst', 'r', encoding='utf-8') as f: + HISTORY = f.read() + +setup( + name='azure-cli-locationbasedservices', + version=VERSION, + description='Microsoft Azure Command-Line Tools Location Based Services Command Module', + long_description=README + '\n\n' + HISTORY, + license='MIT', + author='Microsoft Corporation', + author_email='azpycli@microsoft.com', + url='https://github.com/Azure/azure-cli', + classifiers=CLASSIFIERS, + packages=[ + 'azure', + 'azure.cli', + 'azure.cli.command_modules', + 'azure.cli.command_modules.locationbasedservices' + ], + install_requires=DEPENDENCIES, + cmdclass=cmdclass +)