diff --git a/src/command_modules/azure-cli-acr/README.rst b/src/command_modules/azure-cli-acr/README.rst new file mode 100644 index 00000000000..5b3cf6369c4 --- /dev/null +++ b/src/command_modules/azure-cli-acr/README.rst @@ -0,0 +1,182 @@ +Microsoft Azure CLI 'acr' Command Module +================================== + +Commands to manage Azure container registries +------------- +:: + + Group + az acr: Commands to manage Azure container registries. + + Subgroups: + credential: Manage admin user credential for Azure container registries. + repository: Manage repositories for Azure container registries. + storage : Manage storage accounts for Azure container registries. + + Commands: + create : Create a container registry. + delete : Delete a container registry. + list : List container registries. + show : Get a container registry. + update : Update a container registry. + +Create a container registry +------------- +:: + + Command + az acr create: Create a container registry. + + Arguments + --location -l [Required]: Location. + --name -n [Required]: Name of container registry. + --resource-group -g [Required]: Name of resource group. + --app-id : The app id of an existing service principal. If provided, no + --new-sp or -p should be specified. + --enable-admin : Enable admin user. + --new-sp : Create a new service principal. If provided, no --app-id should + be specified. Optional: Use -p to specify a password. + --password -p : Password used to log into a container registry. + --role -r : Name of role. (Owner, Contributor, Reader). Default: Reader. + --storage-account-name -s : Name of new or existing storage account. If not provided, a + random storage account name will be generated. + + Examples + Create a container registry with a new storage account + az acr create -n myRegistry -g myResourceGroup -l southus + Create a container registry with an existing storage account + az acr create -n myRegistry -g myResourceGroup -l southus -s myStorageAccount + Create a container registry with a new service principal + az acr create -n myRegistry -g myResourceGroup -l southus --new-sp -p myPassword -r Owner + Create a container registry with an existing service principal + az acr create -n myRegistry -g myResourceGroup -l southus --app-id myAppId -r Owner + +Delete a container registry +------------- +:: + + Command + az acr delete: Delete a container registry. + + Arguments + --name -n [Required]: Name of container registry. + --resource-group -g : Name of resource group. + +List container registries +------------- +:: + + Command + az acr list: List container registries. + + Arguments + --resource-group -g: Name of resource group. + + Examples + List container registries and show result in a table + az acr list -o table + List container registries in a resource group and show result in a table + az acr list -g myResourceGroup -o table + +Get a container registry +------------- +:: + + Command + az acr show: Get a container registry. + + Arguments + --name -n [Required]: Name of container registry. + --resource-group -g : Name of resource group. + +Update a container registry +------------- +:: + + Command + az acr update: Update a container registry. + + Arguments + --name -n [Required]: Name of container registry. + --app-id : The app id of an existing service principal. If provided, no --new-sp or + -p should be specified. + --disable-admin : Disable admin user. + --enable-admin : Enable admin user. + --new-sp : Create a new service principal. If provided, no --app-id should be + specified. Optional: Use -p to specify a password. + --password -p : Password used to log into a container registry. + --resource-group -g : Name of resource group. + --role -r : Name of role. (Owner, Contributor, Reader). Default: Reader. + --tags : Space separated tags in 'key[=value]' format. Use "" to clear existing + tags. + --tenant-id -t : Tenant id for service principal login. Warning: Changing tenant id will + invalidate assigned access of existing service principals. + + Examples + Update tags of a container registry + az acr update -n myRegistry --tags key1=value1;key2=value2 + Update a container registry with a new service principal + az acr update -n myRegistry --new-sp -p myPassword -r Owner + Update a container registry with an existing service principal + az acr update -n myRegistry --app-id myAppId -r Owner + +Update storage account for a container registry +------------- +:: + + Command + az acr storage update: Update storage account for a container registry. + + Arguments + --name -n [Required]: Name of container registry. + --storage-account-name -s [Required]: Name of new or existing storage account. + --resource-group -g : Name of resource group. + +Get admin username and password for a container registry +------------- +:: + + Command + az acr credential show: Get admin username and password for a container registry. + + Arguments + --name -n [Required]: Name of container registry. + --resource-group -g : Name of resource group. + +List repositories in a given container registry +------------- +:: + + Command + az acr repository list: List repositories in a given container registry. + + Arguments + --name -n [Required]: Name of container registry. + --password -p : Password used to log into a container registry. + --username -u : Username used to log into a container registry. + + Examples + List repositories in a given container registry if admin user is enabled + az acr repository list -n myRegistry + List repositories in a given container registry with credentials + az acr repository list -n myRegistry -u myUsername -p myPassword + +Show tags of a given repository in a given container registry +------------- +:: + + Command + az acr repository show-tags: Show tags of a given repository in a given container registry. + + Arguments + --name -n [Required]: Name of container registry. + --repository [Required]: The repository to obtain tags from. + --password -p : Password used to log into a container registry. + --username -u : Username used to log into a container registry. + + Examples + Show tags of a given repository in a given container registry if admin user is enabled + az acr repository show-tags -n myRegistry --repository myRepository + Show tags of a given repository in a given container registry with credentials + az acr repository show-tags -n myRegistry --repository myRepository -u myUsername -p + myPassword diff --git a/src/command_modules/azure-cli-acr/azure/__init__.py b/src/command_modules/azure-cli-acr/azure/__init__.py new file mode 100644 index 00000000000..e8f024a89a8 --- /dev/null +++ b/src/command_modules/azure-cli-acr/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-acr/azure/cli/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/__init__.py new file mode 100644 index 00000000000..e8f024a89a8 --- /dev/null +++ b/src/command_modules/azure-cli-acr/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-acr/azure/cli/command_modules/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/__init__.py new file mode 100644 index 00000000000..e8f024a89a8 --- /dev/null +++ b/src/command_modules/azure-cli-acr/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-acr/azure/cli/command_modules/acr/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/__init__.py new file mode 100644 index 00000000000..231e89fa929 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/__init__.py @@ -0,0 +1,13 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +#pylint: disable=unused-import + +import azure.cli.command_modules.acr._help +import azure.cli.command_modules.acr._params +import azure.cli.command_modules.acr.custom +import azure.cli.command_modules.acr.storage +import azure.cli.command_modules.acr.credential +import azure.cli.command_modules.acr.repository diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_arm_utils.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_arm_utils.py new file mode 100644 index 00000000000..050dcfaa419 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_arm_utils.py @@ -0,0 +1,187 @@ +#--------------------------------------------------------------------------------------------- +# 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._util import CLIError +from azure.cli.core.commands.parameters import ( + get_resources_in_subscription, + get_resources_in_resource_group +) + +from azure.cli.command_modules.acr.mgmt_acr.models import Registry + +from ._constants import ( + RESOURCE_PROVIDER, + RESOURCE_TYPE +) +from ._factory import ( + get_arm_service_client, + get_storage_service_client, + get_acr_api_version +) +from ._utils import get_resource_group_name_by_resource_id + +def arm_get_registries_in_subscription(): + '''Returns the list of container registries in the current subscription. + ''' + result = get_resources_in_subscription(RESOURCE_TYPE) + return [Registry(item.id, item.name, item.location, item.tags) for item in result] + +def arm_get_registries_in_resource_group(resource_group_name): + '''Returns the list of container registries in the resource group. + :param str resource_group_name: The name of resource group + ''' + result = get_resources_in_resource_group(resource_group_name, RESOURCE_TYPE) + return [Registry(item.id, item.name, item.location, item.tags) for item in result] + +def _arm_get_resource_by_name(resource_name, resource_type): + '''Returns the ARM resource in the current subscription with resource_name. + :param str resource_name: The name of resource + :param str resource_type: The type of resource + ''' + result = get_resources_in_subscription(resource_type) + elements = [item for item in result if item.name.lower() == resource_name.lower()] + + if len(elements) == 0: + return None + elif len(elements) == 1: + return elements[0] + else: + raise CLIError( + 'More than one resources with type {} are found with name: {}'.format( + resource_type, resource_name)) + +def arm_get_registry_by_name(registry_name): + '''Returns the named container registry. + :param str registry_name: The name of container registry + ''' + return _arm_get_resource_by_name(registry_name, RESOURCE_TYPE) + +def arm_get_storage_account_by_name(storage_account_name): + '''Returns the named storage account. + :param str storage_account_name: The name of storage account + ''' + return _arm_get_resource_by_name(storage_account_name, 'Microsoft.Storage/storageAccounts') + +def arm_deploy_template(resource_group_name, + registry_name, + location, + storage_account_name, + admin_user_enabled): + '''Deploys ARM template to create/update a container registry. + :param str resource_group_name: The name of resource group + :param str registry_name: The name of container registry + :param str location: The name of location + :param str storage_account_name: The name of storage account + :param bool admin_user_enabled: Enable admin user + ''' + from azure.mgmt.resource.resources.models import DeploymentProperties + from azure.cli.core._util import get_file_json + import os + + parameters = _parameters(registry_name, location, storage_account_name, admin_user_enabled) + storage_account_resource_group, _ = _parse_storage_account(storage_account_name) + + if storage_account_resource_group: + file_path = os.path.join(os.path.dirname(__file__), 'template.existing.json') + parameters['storageAccountResourceGroup'] = {'value': storage_account_resource_group} + else: + file_path = os.path.join(os.path.dirname(__file__), 'template.new.json') + parameters['storageAccountType'] = {'value': 'Standard_LRS'} + + template = get_file_json(file_path) + properties = DeploymentProperties(template=template, parameters=parameters, mode='incremental') + + return _arm_deploy_template( + get_arm_service_client().deployments, resource_group_name, properties) + +def _arm_deploy_template(deployments_client, + resource_group_name, + properties, + index=0): + '''Deploys ARM template to create a container registry. + :param obj deployments_client: ARM deployments service client + :param str resource_group_name: The name of resource group + :param DeploymentProperties properties: The properties of a deployment + :param int index: The index added to deployment name to avoid conflict + ''' + if index == 0: + deployment_name = RESOURCE_PROVIDER + elif index > 9: # Just a number to avoid infinite loops + raise CLIError( + 'The resource group {} has too many deployments'.format(resource_group_name)) + else: + deployment_name = RESOURCE_PROVIDER + '_' + str(index) + + try: + deployments_client.validate( + resource_group_name, deployment_name, properties) + return deployments_client.create_or_update( + resource_group_name, deployment_name, properties) + except: #pylint: disable=W0702 + return _arm_deploy_template( + deployments_client, resource_group_name, properties, index + 1) + +def _parameters(registry_name, + location, + storage_account_name, + admin_user_enabled): + '''Returns a dict of deployment parameters. + :param str registry_name: The name of container registry + :param str location: The name of location + :param str storage_account_name: The name of storage account + :param bool admin_user_enabled: Enable admin user + ''' + parameters = { + 'registryName': {'value': registry_name}, + 'registryLocation': {'value': location}, + 'registryApiVersion': {'value': get_acr_api_version()}, + 'storageAccountName': {'value': storage_account_name}, + 'adminUserEnabled': {'value': admin_user_enabled} + } + return parameters + +def _parse_storage_account(storage_account_name): + '''Returns resource group and tags in the storage account. + :param str storage_account_name: The name of storage account + ''' + storage_account = arm_get_storage_account_by_name(storage_account_name) + + if storage_account: + storage_account_resource_group = get_resource_group_name_by_resource_id(storage_account.id) + return storage_account_resource_group, storage_account.tags + else: + return None, None + +def add_tag_storage_account(storage_account_name, registry_name): + '''Add a new tag (key, value) to the storage account. + :param str storage_account_name: The name of storage account + :param str registry_name: The name of container registry + ''' + from azure.mgmt.storage.models import StorageAccountUpdateParameters + storage_account_resource_group, tags = _parse_storage_account(storage_account_name) + + tags[registry_name.lower()] = 'acr' + client = get_storage_service_client().storage_accounts + + return client.update(storage_account_resource_group, + storage_account_name, + StorageAccountUpdateParameters(tags=tags)) + +def delete_tag_storage_account(storage_account_name, registry_name): + '''Delete a tag (key, value) from the storage account, if value matches registry_name. + :param str storage_account_name: The name of storage account + :param str registry_name: The name of container registry + ''' + from azure.mgmt.storage.models import StorageAccountUpdateParameters + storage_account_resource_group, tags = _parse_storage_account(storage_account_name) + registry_name = registry_name.lower() + + if registry_name in tags and tags[registry_name] == 'acr': + del tags[registry_name] + client = get_storage_service_client().storage_accounts + + return client.update(storage_account_resource_group, + storage_account_name, + StorageAccountUpdateParameters(tags=tags)) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_constants.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_constants.py new file mode 100644 index 00000000000..58fc04288a2 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_constants.py @@ -0,0 +1,15 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +RESOURCE_PROVIDER = 'Microsoft.ContainerRegistry' +RESOURCE_TYPE = RESOURCE_PROVIDER + '/registries' + +ALLOWED_ROLES = [ + 'owner', + 'contributor', + 'reader' +] + +DEFAULT_ROLE = 'Reader' diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_factory.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_factory.py new file mode 100644 index 00000000000..4bb8fc679ce --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_factory.py @@ -0,0 +1,66 @@ +#--------------------------------------------------------------------------------------------- +# 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._profile import Profile +from azure.cli.core._config import az_config +from azure.mgmt.resource.resources import ResourceManagementClient +from azure.mgmt.storage import StorageManagementClient +from azure.graphrbac import GraphRbacManagementClient + +from azure.cli.core.commands.client_factory import ( + configure_common_settings, + get_mgmt_service_client +) + +from azure.cli.command_modules.acr.mgmt_acr import ( + ContainerRegistry, + ContainerRegistryConfiguration, + VERSION +) + +import azure.cli.core._logging as _logging +logger = _logging.get_az_logger(__name__) + +def get_arm_service_client(): + '''Returns the client for managing ARM resources. + ''' + return get_mgmt_service_client(ResourceManagementClient) + +def get_storage_service_client(): + '''Returns the client for managing storage accounts. + ''' + return get_mgmt_service_client(StorageManagementClient) + +def get_acr_service_client(): + '''Returns the client for managing container registries. + ''' + profile = Profile() + credentials, subscription_id, _ = profile.get_login_credentials() + + config = ContainerRegistryConfiguration(subscription_id, get_acr_api_version(), credentials) + client = ContainerRegistry(config) + + configure_common_settings(client) + + return client + +def get_graph_mgmt_client(): + '''Returns the client for graph api. + ''' + profile = Profile() + credentials, _, tenant_id = profile.get_login_credentials(True) + client = GraphRbacManagementClient(credentials, tenant_id) + + configure_common_settings(client) + + return client + +def get_acr_api_version(): + '''Returns the api version for container registry + ''' + customized_api_version = az_config.get('acr', 'apiversion', None) + if customized_api_version: + logger.warning('Customized api-version is used: %s', customized_api_version) + return customized_api_version or VERSION diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_format.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_format.py new file mode 100644 index 00000000000..b92402bed0e --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_format.py @@ -0,0 +1,82 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +from collections import OrderedDict + +from ._utils import get_resource_group_name_by_resource_id + +_basic_map = { + 'name': 'NAME', + 'resourceGroup': 'RESOURCE GROUP', + 'location': 'LOCATION', + 'tags': 'TAGS' +} + +_properties_map = { + 'loginServer': 'LOGIN SERVER', + 'creationDate': 'CREATION DATE', + 'adminUserEnabled': 'ADMIN USER ENABLED' +} + +_storage_account_map = { + 'name': 'STORAGE ACCOUNT NAME' +} + +_admin_user_map = { + 'userName': 'USERNAME', + 'passWord': 'PASSWORD' +} + +_order_map = { + 'NAME': 1, + 'RESOURCE GROUP': 2, + 'LOCATION': 3, + 'TAGS': 4, + 'LOGIN SERVER': 11, + 'CREATION DATE': 12, + 'ADMIN USER ENABLED': 13, + 'STORAGE ACCOUNT NAME': 21, + 'USERNAME': 31, + 'PASSWORD': 32 +} + +def output_format(result): + '''Returns the list of container registries each of which is an ordered dictionary. + :param list/dict result: The (list of) container registry object(s) + ''' + obj_list = result if isinstance(result, list) else [result] + return [_format_registry(item) for item in obj_list] + +def _format_registry(item): + '''Returns an ordered dictionary of the container registry. + :param dict item: The container registry object + ''' + basic_info = {_basic_map[key]: str(item[key]) for key in item if key in _basic_map} + + if 'id' in item and item['id']: + resource_group_name = get_resource_group_name_by_resource_id(item['id']) + basic_info['RESOURCE GROUP'] = resource_group_name + + properties_info = {} + storage_account_info = {} + if 'properties' in item and item['properties']: + properties = item['properties'] + properties_info = {_properties_map[key]: str(properties[key]) + for key in properties if key in _properties_map} + + if 'storageAccount' in properties and properties['storageAccount']: + storage_account = properties['storageAccount'] + storage_account_info = {_storage_account_map[key]: str(storage_account[key]) + for key in storage_account if key in _storage_account_map} + + admin_user_info = {_admin_user_map[key]: str(item[key]) + for key in item if key in _admin_user_map} + + all_info = basic_info.copy() + all_info.update(properties_info) + all_info.update(storage_account_info) + all_info.update(admin_user_info) + + return OrderedDict(sorted(all_info.items(), key=lambda t: _order_map[t[0]])) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_help.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_help.py new file mode 100644 index 00000000000..c073d88648d --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_help.py @@ -0,0 +1,92 @@ +#--------------------------------------------------------------------------------------------- +# 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.help_files import helps + +#pylint: disable=line-too-long + +helps['acr'] = """ + type: group + short-summary: Commands to manage Azure container registries. + """ + +helps['acr storage'] = """ + type: group + short-summary: Manage storage accounts for Azure container registries. + """ + +helps['acr credential'] = """ + type: group + short-summary: Manage admin user credential for Azure container registries. + """ + +helps['acr repository'] = """ + type: group + short-summary: Manage repositories for Azure container registries. + """ + +helps['acr list'] = """ + type: command + examples: + - name: List container registries and show result in a table + text: + az acr list -o table + - name: List container registries in a resource group and show result in a table + text: + az acr list -g myResourceGroup -o table + """ + +helps['acr create'] = """ + type: command + examples: + - name: Create a container registry with a new storage account + text: + az acr create -n myRegistry -g myResourceGroup -l southus + - name: Create a container registry with an existing storage account + text: + az acr create -n myRegistry -g myResourceGroup -l southus -s myStorageAccount + - name: Create a container registry with a new service principal + text: + az acr create -n myRegistry -g myResourceGroup -l southus --new-sp -p myPassword -r Owner + - name: Create a container registry with an existing service principal + text: + az acr create -n myRegistry -g myResourceGroup -l southus --app-id myAppId -r Owner + """ + +helps['acr update'] = """ + type: command + examples: + - name: Update tags of a container registry + text: + az acr update -n myRegistry --tags key1=value1;key2=value2 + - name: Update a container registry with a new service principal + text: + az acr update -n myRegistry --new-sp -p myPassword -r Owner + - name: Update a container registry with an existing service principal + text: + az acr update -n myRegistry --app-id myAppId -r Owner + """ + +helps['acr repository list'] = """ + type: command + examples: + - name: List repositories in a given container registry if admin user is enabled + text: + az acr repository list -n myRegistry + - name: List repositories in a given container registry with credentials + text: + az acr repository list -n myRegistry -u myUsername -p myPassword + """ + +helps['acr repository show-tags'] = """ + type: command + examples: + - name: Show tags of a given repository in a given container registry if admin user is enabled + text: + az acr repository show-tags -n myRegistry --repository myRepository + - name: Show tags of a given repository in a given container registry with credentials + text: + az acr repository show-tags -n myRegistry --repository myRepository -u myUsername -p myPassword + """ diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_params.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_params.py new file mode 100644 index 00000000000..beca8846d5b --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_params.py @@ -0,0 +1,77 @@ +#--------------------------------------------------------------------------------------------- +# 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 register_cli_argument +from azure.cli.core.commands.parameters import ( + resource_group_name_type, + location_type, + tags_type, + get_resource_name_completion_list +) + +from ._constants import RESOURCE_TYPE +from ._validators import ( + validate_registry_name_create, + validate_registry_name, + validate_storage_account_name, + validate_resource_group_name, + validate_password, + validate_role +) + +register_cli_argument('acr', 'registry_name', + options_list=('--name', '-n'), + help='Name of container registry', + completer=get_resource_name_completion_list(RESOURCE_TYPE), + validator=validate_registry_name) + +register_cli_argument('acr', 'resource_group_name', resource_group_name_type) +register_cli_argument('acr', 'location', location_type) +register_cli_argument('acr', 'tags', tags_type) + +register_cli_argument('acr', 'storage_account_name', + options_list=('--storage-account-name', '-s'), + help='Name of new or existing storage account', + completer=get_resource_name_completion_list( + 'Microsoft.Storage/storageAccounts'), + validator=validate_storage_account_name) + +register_cli_argument('acr', 'username', + options_list=('--username', '-u'), + help='Username used to log into a container registry') + +register_cli_argument('acr', 'password', + options_list=('--password', '-p'), + help='Password used to log into a container registry') + +register_cli_argument('acr', 'role', + options_list=('--role', '-r'), + help='Name of role. (Owner, Contributor, Reader)', + validator=validate_role) + +register_cli_argument('acr', 'new_sp', + help='Create a new service principal. ' +\ + 'If provided, no --app-id should be specified. ' +\ + 'Optional: Use -p to specify a password.') + +register_cli_argument('acr', 'app_id', + help='The app id of an existing service principal. ' +\ + 'If provided, no --new-sp or -p should be specified.') + +register_cli_argument('acr', 'tenant_id', + options_list=('--tenant-id', '-t'), + help='Tenant id for service principal login. ' +\ + 'Warning: Changing tenant id will invalidate ' +\ + 'assigned access of existing service principals.') + +register_cli_argument('acr create', 'registry_name', completer=None, + validator=validate_registry_name_create) +register_cli_argument('acr create', 'storage_account_name', + help='Name of new or existing storage account. ' +\ + 'If not provided, a random storage account name will be generated.') +register_cli_argument('acr create', 'password', validator=validate_password) +register_cli_argument('acr update', 'password', validator=validate_password) +register_cli_argument('acr create', 'resource_group_name', + validator=validate_resource_group_name) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_utils.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_utils.py new file mode 100644 index 00000000000..9f5b3606d23 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_utils.py @@ -0,0 +1,84 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +import uuid +import datetime + +from azure.graphrbac.models import ServicePrincipalCreateParameters +from azure.cli.core._util import CLIError +from azure.cli.command_modules.role.custom import create_application + +from ._factory import ( + get_acr_service_client, + get_graph_mgmt_client +) + +def _get_registries_in_subscription(): + '''Returns the list of container registries in the current subscription. + ''' + client = get_acr_service_client().registries + return client.list().value #pylint: disable=E1101 + +def _get_registries_in_resource_group(resource_group_name): + '''Returns the list of container registries in the resource group. + :param str resource_group_name: The name of resource group + ''' + client = get_acr_service_client().registries + return client.list_by_resource_group(resource_group_name).value #pylint: disable=E1101 + +def get_registry_by_name(registry_name): + '''Returns the container registry that matches the registry name. + :param str registry_name: The name of container registry + ''' + registries = _get_registries_in_subscription() + elements = [item for item in registries if item.name.lower() == registry_name.lower()] + + if len(elements) == 0: + return None + elif len(elements) == 1: + return elements[0] + else: + raise ValueError('More than one container registries are found with name: ' + registry_name) + +def get_resource_group_name_by_resource_id(resource_id): + '''Returns the resource group name from parsing the resource id. + :param str resource_id: The resource id + ''' + resource_id = resource_id.lower() + resource_group_keyword = '/resourcegroups/' + return resource_id[resource_id.index(resource_group_keyword) + len(resource_group_keyword): + resource_id.index('/providers/')] + +def create_service_principal(registry_name, password=None): + '''Creates an application and a service principal. + :param str registry_name: The name of container registry + :param str password: The password for container registry login + ''' + client = get_graph_mgmt_client() + + start_date = datetime.datetime.now() + app_display_name = registry_name + '-' + start_date.strftime('%Y%m%d%H%M%S') + app_uri = 'http://' + app_display_name # just a valid uri, no need to exist + password_creds = password or str(uuid.uuid4()) + + application = create_application(client.applications, + display_name=app_display_name, + homepage=app_uri, + identifier_uris=[app_uri], + password=password_creds) + + app_id = application.app_id #pylint: disable=E1101 + service_principal = client.service_principals.create( + ServicePrincipalCreateParameters(app_id, True), raw=True) + session_key = service_principal.response.headers._store['ocp-aad-session-key'][1] #pylint: disable=W0212 + + return (app_id, + password_creds, + session_key) + +def registry_not_found(registry_name): + raise CLIError( + 'ERROR: Registry {} cannot be found in the current subscription.'\ + .format(registry_name)) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_validators.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_validators.py new file mode 100644 index 00000000000..95d786feab4 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/_validators.py @@ -0,0 +1,96 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +import re +import uuid + +from azure.cli.command_modules.acr.mgmt_acr.models import RegistryNameCheckRequest + +from azure.cli.core._util import CLIError +from azure.cli.command_modules.storage._factory import storage_client_factory + +from ._constants import ( + RESOURCE_TYPE, + ALLOWED_ROLES +) +from ._factory import ( + get_acr_service_client, + get_arm_service_client +) +from ._arm_utils import arm_get_storage_account_by_name + +import azure.cli.core._logging as _logging +logger = _logging.get_az_logger(__name__) + +def validate_registry_name(namespace): + if namespace.registry_name: + registry_name = namespace.registry_name + if len(registry_name) < 5 or len(registry_name) > 60: + raise CLIError('The registry name must be between 5 and 60 characters.') + + p = re.compile('^([A-Za-z0-9]+)$') + + if not p.match(registry_name): + raise CLIError('The registry name can contain only letters and numbers.') + +def validate_registry_name_create(namespace): + if namespace.registry_name: + client = get_acr_service_client() + + result = client.operation.check_name_availability( + RegistryNameCheckRequest( + namespace.registry_name, + RESOURCE_TYPE + ) + ) + + if not result.name_available: #pylint: disable=E1101 + raise CLIError(result.message) #pylint: disable=E1101 + +def validate_storage_account_name(namespace): + client = storage_client_factory().storage_accounts + + if namespace.storage_account_name: + storage_account_name = namespace.storage_account_name + if arm_get_storage_account_by_name(storage_account_name) is None: + logger.warning('Command to create a storage account:') + logger.warning( + ' az storage account create ' +\ + '-n -g -l --sku Standard_LRS') + logger.warning( + 'The container registry must be at the same location as the storage account.') + raise CLIError( + 'The storage account {} does not exist in the current subscription.'\ + .format(storage_account_name)) + else: + while True: + storage_account_name = str(uuid.uuid4()).replace('-', '')[:24] + if client.check_name_availability(storage_account_name).name_available is True: #pylint: disable=E1101 + namespace.storage_account_name = storage_account_name + logger.warning( + 'New storage account with name %s will be created and used.', + storage_account_name) + return + +def validate_resource_group_name(namespace): + if namespace.resource_group_name: + client = get_arm_service_client() + resource_group_name = namespace.resource_group_name + + if not client.resource_groups.check_existence(resource_group_name): + logger.warning('Command to create a resource group:') + logger.warning(' az resource group create -n -l ') + raise CLIError( + 'The resource group {} does not exist in the current subscription.'\ + .format(resource_group_name)) + +def validate_password(namespace): + if namespace.password and not namespace.new_sp: + raise CLIError('--password has to be used with --new-sp.') + +def validate_role(namespace): + if namespace.role and not namespace.role.lower() in ALLOWED_ROLES: + raise CLIError('The role {} is not allowed. Allowed roles (Owner, Contributor, Reader).'\ + .format(namespace.role)) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/credential.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/credential.py new file mode 100644 index 00000000000..46dedf23226 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/credential.py @@ -0,0 +1,42 @@ +#--------------------------------------------------------------------------------------------- +# 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 cli_command +from azure.cli.core._util import CLIError + +from ._factory import get_acr_service_client + +from ._utils import ( + get_registry_by_name, + get_resource_group_name_by_resource_id, + registry_not_found +) + +from ._format import output_format + +import azure.cli.core._logging as _logging +logger = _logging.get_az_logger(__name__) + +def acr_credential_show(registry_name, resource_group_name=None): + '''Get admin username and password for a container registry. + :param str registry_name: The name of container registry + :param str resource_group_name: The name of resource group + ''' + registry = get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + if resource_group_name is None: + resource_group_name = get_resource_group_name_by_resource_id(registry.id) + + client = get_acr_service_client().registries + if registry.properties.admin_user_enabled: + return client.get_credentials(resource_group_name, registry_name) + else: + raise CLIError( + 'Admin user is not enabled for the container registry with name: {}'\ + .format(registry_name)) + +cli_command('acr credential show', acr_credential_show, table_transformer=output_format) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/custom.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/custom.py new file mode 100644 index 00000000000..a471a0aa559 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/custom.py @@ -0,0 +1,243 @@ +#--------------------------------------------------------------------------------------------- +# 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 ( + cli_command, + LongRunningOperation +) +from azure.cli.core._util import CLIError +from azure.cli.command_modules.role.custom import _create_role_assignment + +from azure.cli.command_modules.acr.mgmt_acr.models import ( + RegistryUpdateParameters, + RegistryPropertiesCreateParameters +) + +from ._constants import ( + DEFAULT_ROLE +) +from ._factory import get_acr_service_client +from ._arm_utils import ( + arm_get_registries_in_subscription, + arm_get_registries_in_resource_group, + arm_get_registry_by_name, + arm_deploy_template, + add_tag_storage_account, + delete_tag_storage_account +) +from ._utils import ( + get_registry_by_name, + get_resource_group_name_by_resource_id, + create_service_principal, + registry_not_found +) + +from ._format import output_format + +import azure.cli.core._logging as _logging +logger = _logging.get_az_logger(__name__) + +def acr_list(resource_group_name=None): + '''List container registries. + :param str resource_group_name: The name of resource group + ''' + if resource_group_name: + return arm_get_registries_in_resource_group(resource_group_name) + else: + return arm_get_registries_in_subscription() + +def acr_create(registry_name, #pylint: disable=too-many-arguments + resource_group_name, + location, + storage_account_name=None, + new_sp=False, + app_id=None, + password=None, + role=DEFAULT_ROLE, + enable_admin=False): + '''Create a container registry. + :param str registry_name: The name of container registry + :param str resource_group_name: The name of resource group + :param str location: The name of location + :param str storage_account_name: The name of storage account + :param bool new_sp: Create a new service principal + :param str app_id: The app id of an existing service principal + :param str password: The password used to log into the container registry + :param str role: The name of role + :param bool enable_admin: Enable admin user + ''' + if new_sp and app_id: + raise CLIError('new-service-principal and app-id should not be specified together.') + + session_key = None + # Create a service principal + if new_sp: + (app_id, + password, + session_key) = create_service_principal(registry_name, password) + + # Create a container registry + LongRunningOperation()( + arm_deploy_template(resource_group_name, + registry_name, + location, + storage_account_name, + enable_admin) + ) + + client = get_acr_service_client().registries + registry = client.get_properties(resource_group_name, registry_name) + add_tag_storage_account(storage_account_name, registry_name) + + logger.warning('\nCreate a new service principal and assign access:') + logger.warning( + ' az ad sp create-for-rbac --scopes %s --role Owner --secret ', + registry.id) #pylint: disable=E1101 + logger.warning('\nUse an existing service principal and assign access:') + logger.warning( + ' az role assignment create --scope %s --role Owner --assignee ', + registry.id) #pylint: disable=E1101 + + # Create role assignment + if app_id: + _create_role_assignment(role, + app_id, + scope=registry.id, #pylint: disable=E1101 + ocp_aad_session_key=session_key) + logger.warning('Service principal has been configured.') + logger.warning(' id(client_id): %s', app_id) + if password: + logger.warning(' password(client_secret): %s', password) + + return registry + +def acr_delete(registry_name, resource_group_name=None): + '''Delete a container registry. + :param str registry_name: The name of container registry + :param str resource_group_name: The name of resource group + ''' + registry = arm_get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + if resource_group_name is None: + resource_group_name = get_resource_group_name_by_resource_id(registry.id) + + client = get_acr_service_client().registries + + storage_account_name = client.get_properties( #pylint: disable=E1101 + resource_group_name, registry_name).properties.storage_account.name + delete_tag_storage_account(storage_account_name, registry_name) + + return client.delete(resource_group_name, registry_name) + +def acr_show(registry_name, resource_group_name=None): + '''Get a container registry. + :param str registry_name: The name of container registry + :param str resource_group_name: The name of resource group + ''' + registry = arm_get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + if resource_group_name is None: + resource_group_name = get_resource_group_name_by_resource_id(registry.id) + + client = get_acr_service_client().registries + + return client.get_properties(resource_group_name, registry_name) + +def acr_update(registry_name, #pylint: disable=too-many-arguments + resource_group_name=None, + tags=None, + new_sp=False, + app_id=None, + password=None, + role=DEFAULT_ROLE, + disable_admin=False, + enable_admin=False, + tenant_id=None): + '''Update a container registry. + :param str registry_name: The name of container registry + :param str resource_group_name: The name of resource group + :param dict tags: The set of tags + :param bool new_sp: Create a new service principal + :param str app_id: The app id of an existing service principal + :param str password: The password used to log into the container registry + :param str role: The name of role + :param bool disable_admin: Disable admin user + :param bool enable_admin: Enable admin user + :param str tenant_id: Tenant id for service principal login + ''' + if new_sp and app_id: + raise CLIError('new_sp and app-id should not be specified together.') + + if disable_admin and enable_admin: + raise CLIError('disable_admin and enable_admin should not be specified together.') + + registry = get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + if resource_group_name is None: + resource_group_name = get_resource_group_name_by_resource_id(registry.id) + + client = get_acr_service_client().registries + + session_key = None + # Create a service principal + if new_sp: + (app_id, + password, + session_key) = create_service_principal(registry_name, password) + + # Create role assignment + if app_id: + _create_role_assignment(role, + app_id, + scope=registry.id, #pylint: disable=E1101 + ocp_aad_session_key=session_key) + logger.warning('Service principal has been configured.') + logger.warning(' id(client_id): %s', app_id) + if password: + logger.warning(' password(client_secret): %s', password) + + # Set admin_user_enabled + admin_user_enabled = None + if disable_admin: + admin_user_enabled = False + if enable_admin: + admin_user_enabled = True + if admin_user_enabled is None: + admin_user_enabled = registry.properties.admin_user_enabled + + # Set tags + newTags = registry.tags + if isinstance(tags, dict): + if tags: + for key in tags: + if tags[key]: + newTags[key] = tags[key] + elif key in newTags: + del newTags[key] + else: + newTags = {} + + return client.update( + resource_group_name, registry_name, + RegistryUpdateParameters( + tags=newTags, + properties=RegistryPropertiesCreateParameters( + tenant_id=tenant_id, + admin_user_enabled=admin_user_enabled + ) + ) + ) + +cli_command('acr list', acr_list, table_transformer=output_format) +cli_command('acr create', acr_create, table_transformer=output_format) +cli_command('acr delete', acr_delete, table_transformer=output_format) +cli_command('acr show', acr_show, table_transformer=output_format) +cli_command('acr update', acr_update, table_transformer=output_format) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/__init__.py new file mode 100644 index 00000000000..ece5117909b --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/__init__.py @@ -0,0 +1,22 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .container_registry import ContainerRegistry, ContainerRegistryConfiguration +from .version import VERSION + +__all__ = [ + 'ContainerRegistry', + 'ContainerRegistryConfiguration' +] + +__version__ = VERSION + diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/container_registry.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/container_registry.py new file mode 100644 index 00000000000..60cb6195786 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/container_registry.py @@ -0,0 +1,94 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.service_client import ServiceClient +from msrest import Configuration, Serializer, Deserializer +from .version import VERSION +from .operations.operation import Operation +from .operations.registries import Registries +from .operations.subscriptions import Subscriptions +from . import models + + +class ContainerRegistryConfiguration(Configuration): + """Configuration for ContainerRegistry + Note that all parameters used to create this instance are saved as instance + attributes. + + :param subscription_id: Gets subscription credentials which uniquely + identify Microsoft Azure subscription.The subscription ID forms part of + the URI for every service call. + :type subscription_id: str + :param api_version: Client Api Version. + :type api_version: str + :param credentials: Subscription credentials which uniquely identify + client subscription. + :type credentials: :mod:`A msrest Authentication + object` + :param str base_url: Service URL + :param str filepath: Existing config + """ + + def __init__( + self, subscription_id, api_version, credentials, base_url=None, filepath=None): + + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") + if api_version is None: + raise ValueError("Parameter 'api_version' must not be None.") + if not isinstance(api_version, str): + raise TypeError("Parameter 'api_version' must be str.") + if credentials is None: + raise ValueError("Parameter 'credentials' must not be None.") + if not base_url: + base_url = 'https://management.azure.com' + + super(ContainerRegistryConfiguration, self).__init__(base_url, filepath) + + self.add_user_agent('containerregistry/{}'.format(VERSION)) + + self.subscription_id = subscription_id + self.api_version = api_version + self.credentials = credentials + + +class ContainerRegistry(object): + """ContainerRegistry + + :param config: Configuration for client. + :type config: ContainerRegistryConfiguration + + :ivar operation: Operation operations + :vartype operation: .operations.Operation + :ivar registries: Registries operations + :vartype registries: .operations.Registries + :ivar subscriptions: Subscriptions operations + :vartype subscriptions: .operations.Subscriptions + """ + + def __init__(self, config): + + self._client = ServiceClient(config.credentials, config) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer() + self._deserialize = Deserializer(client_models) + + self.config = config + self.operation = Operation( + self._client, self.config, self._serialize, self._deserialize) + self.registries = Registries( + self._client, self.config, self._serialize, self._deserialize) + self.subscriptions = Subscriptions( + self._client, self.config, self._serialize, self._deserialize) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/credentials.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/credentials.py new file mode 100644 index 00000000000..a3e369522aa --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/credentials.py @@ -0,0 +1,16 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.authentication import ( + BasicAuthentication, + BasicTokenAuthentication, + OAuthTokenAuthentication) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/exceptions.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/exceptions.py new file mode 100644 index 00000000000..63c04fade09 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/exceptions.py @@ -0,0 +1,22 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.exceptions import ( + ClientException, + SerializationError, + DeserializationError, + TokenExpiredError, + ClientRequestError, + AuthenticationError, + HttpOperationError, + ValidationError, +) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/__init__.py new file mode 100644 index 00000000000..0f7e4c4bc6d --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/__init__.py @@ -0,0 +1,43 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .registry_name_check_request import RegistryNameCheckRequest +from .registry_name_status import RegistryNameStatus +from .registry_move_request import RegistryMoveRequest +from .registry import Registry +from .registry_properties import RegistryProperties +from .storage_account_base_properties import StorageAccountBaseProperties +from .registry_create_parameters import RegistryCreateParameters +from .registry_properties_create_parameters import RegistryPropertiesCreateParameters +from .storage_account_properties import StorageAccountProperties +from .registry_update_parameters import RegistryUpdateParameters +from .resource_list_registry import ResourceListRegistry +from .registry_credentials import RegistryCredentials +from .subscription_notification import SubscriptionNotification +from .subscription_properties import SubscriptionProperties + +__all__ = [ + 'RegistryNameCheckRequest', + 'RegistryNameStatus', + 'RegistryMoveRequest', + 'Registry', + 'RegistryProperties', + 'StorageAccountBaseProperties', + 'RegistryCreateParameters', + 'RegistryPropertiesCreateParameters', + 'StorageAccountProperties', + 'RegistryUpdateParameters', + 'ResourceListRegistry', + 'RegistryCredentials', + 'SubscriptionNotification', + 'SubscriptionProperties', +] diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry.py new file mode 100644 index 00000000000..12f9894e0e1 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry.py @@ -0,0 +1,56 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class Registry(Model): + """Registry + + Variables are only populated by the server, and will be ignored when + sending a request. + + :param id: + :type id: str + :param name: + :type name: str + :param location: + :type location: str + :param tags: + :type tags: dict + :ivar type: + :vartype type: str + :param properties: + :type properties: :class:`RegistryProperties + ` + """ + + _validation = { + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'RegistryProperties'}, + } + + def __init__(self, id=None, name=None, location=None, tags=None, properties=None): + self.id = id + self.name = name + self.location = location + self.tags = tags + self.type = None + self.properties = properties diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_create_parameters.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_create_parameters.py new file mode 100644 index 00000000000..676cafc8570 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_create_parameters.py @@ -0,0 +1,56 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryCreateParameters(Model): + """RegistryCreateParameters + + Variables are only populated by the server, and will be ignored when + sending a request. + + :param id: + :type id: str + :param name: + :type name: str + :param location: + :type location: str + :param tags: + :type tags: dict + :ivar type: + :vartype type: str + :param properties: + :type properties: :class:`RegistryPropertiesCreateParameters + ` + """ + + _validation = { + 'type': {'readonly': True}, + } + + _attribute_map = { + 'id': {'key': 'id', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '{str}'}, + 'type': {'key': 'type', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'RegistryPropertiesCreateParameters'}, + } + + def __init__(self, id=None, name=None, location=None, tags=None, properties=None): + self.id = id + self.name = name + self.location = location + self.tags = tags + self.type = None + self.properties = properties diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_credentials.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_credentials.py new file mode 100644 index 00000000000..abb5423acf5 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_credentials.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. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryCredentials(Model): + """RegistryCredentials + + :param user_name: + :type user_name: str + :param pass_word: + :type pass_word: str + """ + + _attribute_map = { + 'user_name': {'key': 'userName', 'type': 'str'}, + 'pass_word': {'key': 'passWord', 'type': 'str'}, + } + + def __init__(self, user_name=None, pass_word=None): + self.user_name = user_name + self.pass_word = pass_word diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_move_request.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_move_request.py new file mode 100644 index 00000000000..2e36f518931 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_move_request.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. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryMoveRequest(Model): + """RegistryMoveRequest + + :param target_resource_group: + :type target_resource_group: str + :param resources: + :type resources: list of str + """ + + _attribute_map = { + 'target_resource_group': {'key': 'targetResourceGroup', 'type': 'str'}, + 'resources': {'key': 'resources', 'type': '[str]'}, + } + + def __init__(self, target_resource_group=None, resources=None): + self.target_resource_group = target_resource_group + self.resources = resources diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_check_request.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_check_request.py new file mode 100644 index 00000000000..c78bb196152 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_check_request.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. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryNameCheckRequest(Model): + """RegistryNameCheckRequest + + :param name: + :type name: str + :param type: + :type type: str + """ + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + 'type': {'key': 'type', 'type': 'str'}, + } + + def __init__(self, name=None, type=None): + self.name = name + self.type = type diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_status.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_status.py new file mode 100644 index 00000000000..e36611d0306 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_name_status.py @@ -0,0 +1,36 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryNameStatus(Model): + """RegistryNameStatus + + :param name_available: + :type name_available: bool + :param reason: + :type reason: str + :param message: + :type message: str + """ + + _attribute_map = { + 'name_available': {'key': 'nameAvailable', 'type': 'bool'}, + 'reason': {'key': 'reason', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + } + + def __init__(self, name_available=None, reason=None, message=None): + self.name_available = name_available + self.reason = reason + self.message = message diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties.py new file mode 100644 index 00000000000..cd4cf71982f --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties.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. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryProperties(Model): + """RegistryProperties + + :param storage_account: + :type storage_account: :class:`StorageAccountBaseProperties + ` + :param login_server: + :type login_server: str + :param creation_date: + :type creation_date: datetime + :param admin_user_enabled: + :type admin_user_enabled: bool + """ + + _attribute_map = { + 'storage_account': {'key': 'storageAccount', 'type': 'StorageAccountBaseProperties'}, + 'login_server': {'key': 'loginServer', 'type': 'str'}, + 'creation_date': {'key': 'creationDate', 'type': 'iso-8601'}, + 'admin_user_enabled': {'key': 'adminUserEnabled', 'type': 'bool'}, + } + + def __init__(self, storage_account=None, login_server=None, creation_date=None, admin_user_enabled=None): + self.storage_account = storage_account + self.login_server = login_server + self.creation_date = creation_date + self.admin_user_enabled = admin_user_enabled diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties_create_parameters.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties_create_parameters.py new file mode 100644 index 00000000000..ba5a1a9c8ae --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_properties_create_parameters.py @@ -0,0 +1,37 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryPropertiesCreateParameters(Model): + """RegistryPropertiesCreateParameters + + :param tenant_id: + :type tenant_id: str + :param admin_user_enabled: + :type admin_user_enabled: bool + :param storage_account: + :type storage_account: :class:`StorageAccountProperties + ` + """ + + _attribute_map = { + 'tenant_id': {'key': 'tenantId', 'type': 'str'}, + 'admin_user_enabled': {'key': 'adminUserEnabled', 'type': 'bool'}, + 'storage_account': {'key': 'storageAccount', 'type': 'StorageAccountProperties'}, + } + + def __init__(self, tenant_id=None, admin_user_enabled=None, storage_account=None): + self.tenant_id = tenant_id + self.admin_user_enabled = admin_user_enabled + self.storage_account = storage_account diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_update_parameters.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_update_parameters.py new file mode 100644 index 00000000000..8f4ef8e37fa --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/registry_update_parameters.py @@ -0,0 +1,33 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class RegistryUpdateParameters(Model): + """RegistryUpdateParameters + + :param tags: + :type tags: dict + :param properties: + :type properties: :class:`RegistryPropertiesCreateParameters + ` + """ + + _attribute_map = { + 'tags': {'key': 'tags', 'type': '{str}'}, + 'properties': {'key': 'properties', 'type': 'RegistryPropertiesCreateParameters'}, + } + + def __init__(self, tags=None, properties=None): + self.tags = tags + self.properties = properties diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/resource_list_registry.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/resource_list_registry.py new file mode 100644 index 00000000000..6a213c46e37 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/resource_list_registry.py @@ -0,0 +1,28 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class ResourceListRegistry(Model): + """ResourceListRegistry + + :param value: + :type value: list of :class:`Registry ` + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Registry]'}, + } + + def __init__(self, value=None): + self.value = value diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_base_properties.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_base_properties.py new file mode 100644 index 00000000000..c9d5bc7651a --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_base_properties.py @@ -0,0 +1,28 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class StorageAccountBaseProperties(Model): + """StorageAccountBaseProperties + + :param name: + :type name: str + """ + + _attribute_map = { + 'name': {'key': 'name', 'type': 'str'}, + } + + def __init__(self, name=None): + self.name = name diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_properties.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_properties.py new file mode 100644 index 00000000000..7f9f554436c --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/storage_account_properties.py @@ -0,0 +1,40 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class StorageAccountProperties(Model): + """StorageAccountProperties + + :param access_key: + :type access_key: str + :param end_point_url: + :type end_point_url: str + :param location: + :type location: str + :param name: + :type name: str + """ + + _attribute_map = { + 'access_key': {'key': 'accessKey', 'type': 'str'}, + 'end_point_url': {'key': 'endPointUrl', 'type': 'str'}, + 'location': {'key': 'location', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + } + + def __init__(self, access_key=None, end_point_url=None, location=None, name=None): + self.access_key = access_key + self.end_point_url = end_point_url + self.location = location + self.name = name diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_notification.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_notification.py new file mode 100644 index 00000000000..0b8073c313b --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_notification.py @@ -0,0 +1,38 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class SubscriptionNotification(Model): + """SubscriptionNotification + + :param registration_date: + :type registration_date: datetime + :param state: Possible values include: 'NotDefined', 'Registered', + 'Unregistered', 'Warned', 'Suspended', 'Deleted' + :type state: str + :param properties: + :type properties: :class:`SubscriptionProperties + ` + """ + + _attribute_map = { + 'registration_date': {'key': 'registrationDate', 'type': 'iso-8601'}, + 'state': {'key': 'state', 'type': 'str'}, + 'properties': {'key': 'properties', 'type': 'SubscriptionProperties'}, + } + + def __init__(self, registration_date=None, state=None, properties=None): + self.registration_date = registration_date + self.state = state + self.properties = properties diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_properties.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_properties.py new file mode 100644 index 00000000000..d2227758a3a --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/models/subscription_properties.py @@ -0,0 +1,36 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model + + +class SubscriptionProperties(Model): + """SubscriptionProperties + + :param tenant_id: + :type tenant_id: str + :param location_placement_id: + :type location_placement_id: str + :param quota_id: + :type quota_id: str + """ + + _attribute_map = { + 'tenant_id': {'key': 'tenantId', 'type': 'str'}, + 'location_placement_id': {'key': 'locationPlacementId', 'type': 'str'}, + 'quota_id': {'key': 'quotaId', 'type': 'str'}, + } + + def __init__(self, tenant_id=None, location_placement_id=None, quota_id=None): + self.tenant_id = tenant_id + self.location_placement_id = location_placement_id + self.quota_id = quota_id diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/__init__.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/__init__.py new file mode 100644 index 00000000000..dd08efaa7d8 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/__init__.py @@ -0,0 +1,21 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .operation import Operation +from .registries import Registries +from .subscriptions import Subscriptions + +__all__ = [ + 'Operation', + 'Registries', + 'Subscriptions', +] diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/operation.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/operation.py new file mode 100644 index 00000000000..21c31075397 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/operation.py @@ -0,0 +1,141 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.pipeline import ClientRawResponse +from msrest.exceptions import HttpOperationError + +from .. import models + + +class Operation(object): + """Operation operations. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An objec model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + + self._client = client + self._serialize = serializer + self._deserialize = deserializer + + self.config = config + + def check_name_availability( + self, name_check_request, custom_headers={}, raw=False, **operation_config): + """ + + :param name_check_request: + :type name_check_request: :class:`RegistryNameCheckRequest + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`RegistryNameStatus + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/providers/Microsoft.ContainerRegistry/checkNameAvailability' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(name_check_request, 'RegistryNameCheckRequest') + + # Construct and send request + request = self._client.post(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('RegistryNameStatus', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def move_resources( + self, resource_group, move_request, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param move_request: + :type move_request: :class:`RegistryMoveRequest + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: None + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/moveResources' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(move_request, 'RegistryMoveRequest') + + # Construct and send request + request = self._client.post(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + if raw: + client_raw_response = ClientRawResponse(None, response) + return client_raw_response diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/registries.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/registries.py new file mode 100644 index 00000000000..945091678ff --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/registries.py @@ -0,0 +1,414 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.pipeline import ClientRawResponse +from msrest.exceptions import HttpOperationError + +from .. import models + + +class Registries(object): + """Registries operations. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An objec model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + + self._client = client + self._serialize = serializer + self._deserialize = deserializer + + self.config = config + + def get_properties( + self, resource_group, registry_name, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param registry_name: + :type registry_name: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`Registry ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries/{registryName}' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str'), + 'registryName': self._serialize.url("registry_name", registry_name, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('Registry', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def create( + self, resource_group, registry_name, registry_parameters, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param registry_name: + :type registry_name: str + :param registry_parameters: + :type registry_parameters: :class:`RegistryCreateParameters + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`RegistryCreateParameters + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries/{registryName}' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str'), + 'registryName': self._serialize.url("registry_name", registry_name, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(registry_parameters, 'RegistryCreateParameters') + + # Construct and send request + request = self._client.put(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('RegistryCreateParameters', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def delete( + self, resource_group, registry_name, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param registry_name: + :type registry_name: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: None + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries/{registryName}' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str'), + 'registryName': self._serialize.url("registry_name", registry_name, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.delete(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + if raw: + client_raw_response = ClientRawResponse(None, response) + return client_raw_response + + def update( + self, resource_group, registry_name, registry_update_parameters, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param registry_name: + :type registry_name: str + :param registry_update_parameters: + :type registry_update_parameters: :class:`RegistryUpdateParameters + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`Registry ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries/{registryName}' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str'), + 'registryName': self._serialize.url("registry_name", registry_name, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(registry_update_parameters, 'RegistryUpdateParameters') + + # Construct and send request + request = self._client.patch(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('Registry', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def list_by_resource_group( + self, resource_group, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`ResourceListRegistry + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('ResourceListRegistry', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def list( + self, custom_headers={}, raw=False, **operation_config): + """ + + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`ResourceListRegistry + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/providers/Microsoft.ContainerRegistry/registries' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('ResourceListRegistry', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def get_credentials( + self, resource_group, registry_name, custom_headers={}, raw=False, **operation_config): + """ + + :param resource_group: + :type resource_group: str + :param registry_name: + :type registry_name: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`RegistryCredentials + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.ContainerRegistry/registries/{registryName}/GetCredentials' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str'), + 'resourceGroup': self._serialize.url("resource_group", resource_group, 'str'), + 'registryName': self._serialize.url("registry_name", registry_name, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.post(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('RegistryCredentials', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/subscriptions.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/subscriptions.py new file mode 100644 index 00000000000..4cb592677f5 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/operations/subscriptions.py @@ -0,0 +1,90 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.pipeline import ClientRawResponse +from msrest.exceptions import HttpOperationError + +from .. import models + + +class Subscriptions(object): + """Subscriptions operations. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An objec model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + + self._client = client + self._serialize = serializer + self._deserialize = deserializer + + self.config = config + + def put_subscription( + self, notification, custom_headers={}, raw=False, **operation_config): + """ + + :param notification: + :type notification: :class:`SubscriptionNotification + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: :class:`SubscriptionNotification + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/subscriptions/{subscriptionId}' + path_format_arguments = { + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + query_parameters['api-version'] = self._serialize.query("self.config.api_version", self.config.api_version, 'str') + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(notification, 'SubscriptionNotification') + + # Construct and send request + request = self._client.put(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise HttpOperationError(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('SubscriptionNotification', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/version.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/version.py new file mode 100644 index 00000000000..0a50b7028eb --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/mgmt_acr/version.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. +#--------------------------------------------------------------------------------------------- +#pylint: skip-file +# coding=utf-8 +# -------------------------------------------------------------------------- +# Code generated by Microsoft (R) AutoRest Code Generator 0.16.0.0 +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +VERSION = "2016-06-27-preview" + diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/repository.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/repository.py new file mode 100644 index 00000000000..7e9139dc255 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/repository.py @@ -0,0 +1,85 @@ +#--------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +#--------------------------------------------------------------------------------------------- + +import requests + +from azure.cli.core.commands import cli_command +from azure.cli.core._util import CLIError + +from ._utils import ( + get_registry_by_name, + registry_not_found +) +from .credential import acr_credential_show + +def _obtain_data_from_registry(login_server, path, resultIndex, username, password): + registryEndpoint = 'https://' + login_server + resultList = [] + executeNextHttpCall = True + + while executeNextHttpCall: + executeNextHttpCall = False + response = requests.get( + registryEndpoint + path, + auth=requests.auth.HTTPBasicAuth( + username, + password + ) + ) + + if response.status_code == 200: + resultList += response.json()[resultIndex] + if 'link' in response.headers and response.headers['link']: + linkHeader = response.headers['link'] + # The registry is telling us there's more items in the list, + # and another call is needed. The link header looks something + # like `Link: ; rel="next"` + # we should follow the next path indicated in the link header + path = linkHeader[(linkHeader.index('<')+1):linkHeader.index('>')] + executeNextHttpCall = True + else: + response.raise_for_status() + + return {resultIndex: resultList} + +def _validate_user_credentials(registry_name, path, resultIndex, username=None, password=None): + registry = get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + login_server = registry.properties.login_server + + if username and password: + return _obtain_data_from_registry(login_server, path, resultIndex, username, password) + + try: + cred = acr_credential_show(registry_name) + username = cred.user_name + password = cred.pass_word + return _obtain_data_from_registry(login_server, path, resultIndex, username, password) + except: #pylint: disable=W0702 + raise CLIError('Login credentials cannot be obtained. Please enter username/password') + +def acr_repository_list(registry_name, username=None, password=None): + '''List repositories in a given container registry. + :param str registry_name: The name of container registry + :param str username: The username used to log into the container registry + :param str password: The password used to log into the container registry + ''' + path = '/v2/_catalog' + return _validate_user_credentials(registry_name, path, 'repositories', username, password) + +def acr_repository_show_tags(registry_name, repository, username=None, password=None): + '''Show tags of a given repository in a given container registry. + :param str registry_name: The name of container registry + :param str repository: The repository to obtain tags from + :param str username: The username used to log into the container registry + :param str password: The password used to log into the container registry + ''' + path = '/v2/' + repository + '/tags/list' + return _validate_user_credentials(registry_name, path, 'tags', username, password) + +cli_command('acr repository list', acr_repository_list) +cli_command('acr repository show-tags', acr_repository_show_tags) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/storage.py b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/storage.py new file mode 100644 index 00000000000..746ace9f3c4 --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/storage.py @@ -0,0 +1,58 @@ +#--------------------------------------------------------------------------------------------- +# 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 ( + cli_command, + LongRunningOperation +) + +from ._factory import get_acr_service_client +from ._arm_utils import ( + arm_deploy_template, + add_tag_storage_account, + delete_tag_storage_account +) +from ._utils import ( + get_registry_by_name, + get_resource_group_name_by_resource_id, + registry_not_found +) +from ._format import output_format + +def acr_storage_update(registry_name, + storage_account_name, + resource_group_name=None): + '''Update storage account for a container registry. + :param str registry_name: The name of container registry + :param str storage_account_name: The name of storage account + :param str resource_group_name: The name of resource group + ''' + registry = get_registry_by_name(registry_name) + if registry is None: + registry_not_found(registry_name) + + if resource_group_name is None: + resource_group_name = get_resource_group_name_by_resource_id(registry.id) + + old_storage_account_name = registry.properties.storage_account.name + + # Update a container registry + LongRunningOperation()( + arm_deploy_template(resource_group_name, + registry_name, + registry.location, + storage_account_name, + registry.properties.admin_user_enabled) + ) + + client = get_acr_service_client().registries + registry = client.get_properties(resource_group_name, registry_name) + + delete_tag_storage_account(old_storage_account_name, registry_name) + add_tag_storage_account(storage_account_name, registry_name) + + return registry + +cli_command('acr storage update', acr_storage_update, table_transformer=output_format) diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.existing.json b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.existing.json new file mode 100644 index 00000000000..98bd399f1ff --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.existing.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Name of the registry service" + } + }, + "registryLocation": { + "type": "string", + "metadata": { + "description": "Location of the registry service" + } + }, + "registryApiVersion": { + "type": "string", + "defaultValue": "2016-06-27-preview", + "metadata": { + "description": "Api version of the registry service" + } + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "Name of the storage account" + } + }, + "storageAccountResourceGroup": { + "type": "string", + "metadata": { + "description": "Resource group of the storage account" + } + }, + "adminUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Enable admin user" + } + } + }, + "resources": [ + { + "name": "[parameters('registryName')]", + "type": "Microsoft.ContainerRegistry/registries", + "location": "[parameters('registryLocation')]", + "apiVersion": "[parameters('registryApiVersion')]", + "tags": { + "storageaccount": "[parameters('storageAccountName')]" + }, + "properties": { + "tenantId": "[subscription().tenantId]", + "adminUserEnabled": "[parameters('adminUserEnabled')]", + "storageAccount": { + "name": "[parameters('storageAccountName')]", + "accessKey": "[listKeys(resourceId(parameters('storageAccountResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2016-01-01').keys[0].value]", + "endPointUrl": "[reference(resourceId(parameters('storageAccountResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2016-01-01').primaryEndpoints.blob]" + } + } + } + ] +} \ No newline at end of file diff --git a/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.new.json b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.new.json new file mode 100644 index 00000000000..a5fc188933c --- /dev/null +++ b/src/command_modules/azure-cli-acr/azure/cli/command_modules/acr/template.new.json @@ -0,0 +1,77 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Name of the registry service" + } + }, + "registryLocation": { + "type": "string", + "metadata": { + "description": "Location of the registry service" + } + }, + "registryApiVersion": { + "type": "string", + "defaultValue": "2016-06-27-preview", + "metadata": { + "description": "Api version of the registry service" + } + }, + "storageAccountName": { + "type": "string", + "metadata": { + "description": "Name of the storage account" + } + }, + "storageAccountType": { + "type": "string", + "metadata": { + "description": "Type of the storage account" + } + }, + "adminUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Enable admin user" + } + } + }, + "resources": [ + { + "name": "[parameters('storageAccountName')]", + "type": "Microsoft.Storage/storageAccounts", + "location": "[parameters('registryLocation')]", + "apiVersion": "2016-01-01", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "kind": "Storage" + }, + { + "name": "[parameters('registryName')]", + "type": "Microsoft.ContainerRegistry/registries", + "location": "[parameters('registryLocation')]", + "apiVersion": "[parameters('registryApiVersion')]", + "tags": { + "storageaccount": "[parameters('storageAccountName')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]" + ], + "properties": { + "tenantId": "[subscription().tenantId]", + "adminUserEnabled": "[parameters('adminUserEnabled')]", + "storageAccount": { + "name": "[parameters('storageAccountName')]", + "accessKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2016-01-01').keys[0].value]", + "endPointUrl": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2016-01-01').primaryEndpoints.blob]" + } + } + } + ] +} \ No newline at end of file diff --git a/src/command_modules/azure-cli-acr/requirements.txt b/src/command_modules/azure-cli-acr/requirements.txt new file mode 100644 index 00000000000..525837d8ad6 --- /dev/null +++ b/src/command_modules/azure-cli-acr/requirements.txt @@ -0,0 +1 @@ +azure==2.0.0rc6 diff --git a/src/command_modules/azure-cli-acr/setup.py b/src/command_modules/azure-cli-acr/setup.py new file mode 100644 index 00000000000..a99a43803ef --- /dev/null +++ b/src/command_modules/azure-cli-acr/setup.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +#--------------------------------------------------------------------------------------------- +# 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 + +VERSION = '0.0.5' + +CLASSIFIERS = [ + 'Development Status :: 3 - Alpha', + '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', + 'License :: OSI Approved :: MIT License', +] + +DEPENDENCIES = [ + 'azure==2.0.0rc6', +] + +with open('README.rst', 'r', encoding='utf-8') as f: + README = f.read() + +setup( + name='azure-cli-acr', + version=VERSION, + description='Microsoft Azure Command-Line Tools', + long_description=README, + license='MIT', + author='Microsoft Corporation', + author_email='azpycli@microsoft.com', + url='https://github.com/Azure/azure-cli', + classifiers=CLASSIFIERS, + namespace_packages = [ + 'azure', + 'azure.cli', + 'azure.cli.command_modules', + ], + packages=[ + 'azure.cli.command_modules.acr', + 'azure.cli.command_modules.acr.mgmt_acr', + 'azure.cli.command_modules.acr.mgmt_acr.models', + 'azure.cli.command_modules.acr.mgmt_acr.operations', + ], + install_requires=DEPENDENCIES, + package_data={'azure.cli.command_modules.acr': ['template.new.json', 'template.existing.json']}, +)