Skip to content

Commit

Permalink
[ACR]: private link and CMK support (#12381)
Browse files Browse the repository at this point in the history
  • Loading branch information
yugangw-msft authored Mar 4, 2020
1 parent 71a9ab2 commit 74c3e5c
Show file tree
Hide file tree
Showing 32 changed files with 7,310 additions and 1,673 deletions.
Binary file not shown.
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/profiles/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def default_api_version(self):
'role_definitions': '2018-01-01-preview',
'provider_operations_metadata': '2018-01-01-preview'
}),
ResourceType.MGMT_CONTAINERREGISTRY: '2019-06-01-preview',
ResourceType.MGMT_CONTAINERREGISTRY: '2019-12-01-preview',
ResourceType.DATA_KEYVAULT: '7.0',
ResourceType.DATA_STORAGE: '2018-11-09',
ResourceType.DATA_COSMOS_TABLE: '2017-04-17',
Expand Down
10 changes: 7 additions & 3 deletions src/azure-cli/azure/cli/command_modules/acr/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@

def get_acr_service_client(cli_ctx, api_version=None):
"""Returns the client for managing container registries. """
from azure.mgmt.containerregistry import ContainerRegistryManagementClient
return get_mgmt_service_client(cli_ctx, ContainerRegistryManagementClient, api_version=api_version)
from azure.cli.core.profiles import ResourceType
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_CONTAINERREGISTRY, api_version=api_version)


def cf_acr_registries(cli_ctx, *_):
return get_acr_service_client(cli_ctx).registries


def cf_acr_registries_tasks(cli_ctx, *_):
return get_acr_service_client(cli_ctx, VERSION_2019_06_01_PREVIEW).registries
return get_acr_service_client(cli_ctx, api_version=VERSION_2019_06_01_PREVIEW).registries


def cf_acr_replications(cli_ctx, *_):
Expand All @@ -31,6 +31,10 @@ def cf_acr_webhooks(cli_ctx, *_):
return get_acr_service_client(cli_ctx).webhooks


def cf_acr_private_endpoint_connections(cli_ctx, *_):
return get_acr_service_client(cli_ctx).private_endpoint_connections


def cf_acr_tasks(cli_ctx, *_):
return get_acr_service_client(cli_ctx, VERSION_2019_06_01_PREVIEW).tasks

Expand Down
6 changes: 4 additions & 2 deletions src/azure-cli/azure/cli/command_modules/acr/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long

from azure.cli.core.profiles import ResourceType

ACR_RESOURCE_PROVIDER = 'Microsoft.ContainerRegistry'
REGISTRY_RESOURCE_TYPE = ACR_RESOURCE_PROVIDER + '/registries'
WEBHOOK_RESOURCE_TYPE = REGISTRY_RESOURCE_TYPE + '/webhooks'
Expand Down Expand Up @@ -66,6 +68,6 @@ def get_succeeded_run_status(cmd):
return [RunStatus.succeeded.value]


def get_acr_models(cmd):
from azure.cli.core.profiles import ResourceType, get_sdk
def get_acr_task_models(cmd):
from azure.cli.core.profiles import get_sdk
return get_sdk(cmd.cli_ctx, ResourceType.MGMT_CONTAINERREGISTRY, 'models')
82 changes: 82 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acr/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1137,3 +1137,85 @@
text: >
az acr webhook update -n MyWebhook -r MyRegistry --status disabled
"""

# region private-endpoint-connection
# be careful to keep long-summary consistent in this region
helps['acr private-endpoint-connection'] = """
type: group
short-summary: Manage container registry private endpoint connections
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""

helps['acr private-endpoint-connection approve'] = """
type: command
short-summary: Approve a private endpoint connection request for a container registry
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""

helps['acr private-endpoint-connection reject'] = """
type: command
short-summary: Reject a private endpoint connection request for a container registry
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""

helps['acr private-endpoint-connection list'] = """
type: command
short-summary: List all private endpoint connections to a container registry
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""

helps['acr private-endpoint-connection show'] = """
type: command
short-summary: Show details of a container registry's private endpoint connection
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""

helps['acr private-endpoint-connection delete'] = """
type: command
short-summary: Delete a private endpoint connection request for a container registry
long-summary: To create a private endpoint connection use "az network private-endpoint create". For more information see https://aka.ms/acr/private-link
"""
# endregion

# region encryption
helps['acr encryption'] = """
type: group
short-summary: Manage container registry encryption
long-summary: For more information, see http://aka.ms/acr/cmk
"""

helps['acr encryption rotate-key'] = """
type: command
short-summary: Rotate (update) the container registry's encryption key
long-summary: For more information, see http://aka.ms/acr/cmk
"""

helps['acr encryption show'] = """
type: command
short-summary: Show the container registry's encryption details
long-summary: For more information, see http://aka.ms/acr/cmk
"""
# endregion

# region identity
helps['acr identity'] = """
type: group
short-summary: Manage service (managed) identities for a container registry
"""

helps['acr identity assign'] = """
type: command
short-summary: Assign a managed identity to a container registry
long-summary: Managed identities can be user-assigned or system-assigned
"""

helps['acr identity remove'] = """
type: command
short-summary: Remove a managed identity from a container registry
"""

helps['acr identity show'] = """
type: command
short-summary: Show the container registry's identity details
"""
# endregion
27 changes: 25 additions & 2 deletions src/azure-cli/azure/cli/command_modules/acr/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@


def load_arguments(self, _): # pylint: disable=too-many-statements
SkuName, PasswordName, DefaultAction, PolicyStatus, WebhookAction, WebhookStatus, TaskStatus, BaseImageTriggerType, RunStatus, SourceRegistryLoginMode, UpdateTriggerPayloadType, TokenStatus = self.get_models(
'SkuName', 'PasswordName', 'DefaultAction', 'PolicyStatus', 'WebhookAction', 'WebhookStatus', 'TaskStatus', 'BaseImageTriggerType', 'RunStatus', 'SourceRegistryLoginMode', 'UpdateTriggerPayloadType', 'TokenStatus')
SkuName, PasswordName, DefaultAction, PolicyStatus, WebhookAction, WebhookStatus, TaskStatus, \
BaseImageTriggerType, RunStatus, SourceRegistryLoginMode, UpdateTriggerPayloadType, TokenStatus = self.get_models(
'SkuName', 'PasswordName', 'DefaultAction', 'PolicyStatus', 'WebhookAction', 'WebhookStatus',
'TaskStatus', 'BaseImageTriggerType', 'RunStatus', 'SourceRegistryLoginMode', 'UpdateTriggerPayloadType',
'TokenStatus')

with self.argument_context('acr') as c:
c.argument('tags', arg_type=tags_type)
c.argument('registry_name', options_list=['--name', '-n'], help='The name of the container registry. You can configure the default registry name using `az configure --defaults acr=<registry name>`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE), configured_default='acr')
Expand Down Expand Up @@ -75,6 +79,10 @@ def load_arguments(self, _): # pylint: disable=too-many-statements
c.argument('default_action', arg_type=get_enum_type(DefaultAction),
help='Default action to apply when no rule matches. Only applicable to Premium SKU.')

with self.argument_context('acr create', arg_group="Customer managed key", is_preview=True) as c:
c.argument('identity', help="Use assigned managed identity resource id or name if in the same resource group")
c.argument('key_encryption_key', help="key vault key uri")

with self.argument_context('acr import') as c:
c.argument('source_image', options_list=['--source'], help="The source identifier will be either a source image name or a fully qualified source.")
c.argument('source_registry', options_list=['--registry', '-r'], help='The source container registry can be name, login server or resource ID of the source registry.')
Expand Down Expand Up @@ -316,6 +324,21 @@ def load_arguments(self, _): # pylint: disable=too-many-statements
c.argument('password1', options_list=['--password1'], help='Flag indicating if first password should be deleted', action='store_true', required=False)
c.argument('password2', options_list=['--password2'], help='Flag indicating if second password should be deleted.', action='store_true', required=False)

with self.argument_context('acr private-endpoint-connection') as c:
# to match private_endpoint_connection_command_guideline.md guidelines
c.argument('registry_name', options_list=['--registry-name', '-r'], help='The name of the container registry. You can configure the default registry name using `az configure --defaults acr=<registry name>`', completer=get_resource_name_completion_list(REGISTRY_RESOURCE_TYPE), configured_default='acr')
c.argument('private_endpoint_connection_name', options_list=['--name', '-n'], help='The name of the private endpoint connection')

c.argument('approval_description', options_list=['--description'], help='Approval description. For example, the reason for approval.')
c.argument('rejection_description', options_list=['--description'], help='Rejection description. For example, the reason for rejection.')

with self.argument_context('acr identity') as c:
c.argument('identities', nargs='+', help="Space-separated identities. Use '[system]' to refer to the system assigned identity")

with self.argument_context('acr encryption') as c:
c.argument('key_encryption_key', help="key vault key uri")
c.argument('identity', help="client id of managed identity, resource name or id of user assigned identity. Use '[system]' to refer to the system assigned identity")


def _get_helm_default_install_location():
exe_name = 'helm'
Expand Down
4 changes: 2 additions & 2 deletions src/azure-cli/azure/cli/command_modules/acr/_run_polling.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from msrest.polling import PollingMethod, LROPoller
from msrestazure.azure_exceptions import CloudError

from ._constants import get_acr_models, get_finished_run_status, get_succeeded_run_status
from ._constants import get_acr_task_models, get_finished_run_status, get_succeeded_run_status


def get_run_with_polling(cmd,
Expand All @@ -18,7 +18,7 @@ def get_run_with_polling(cmd,
registry_name,
resource_group_name):
deserializer = Deserializer(
{k: v for k, v in get_acr_models(cmd).__dict__.items() if isinstance(v, type)})
{k: v for k, v in get_acr_task_models(cmd).__dict__.items() if isinstance(v, type)})

def deserialize_run(response):
return deserializer('Run', response)
Expand Down
4 changes: 2 additions & 2 deletions src/azure-cli/azure/cli/command_modules/acr/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

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

from knack.prompting import prompt_y_n, NoTTYException
from azure.cli.core.commands.parameters import get_resources_in_subscription

Expand Down Expand Up @@ -313,8 +314,7 @@ def get_custom_registry_credentials(cmd,
CustomRegistryCredentials, SecretObject, SecretObjectType = cmd.get_models(
'CustomRegistryCredentials',
'SecretObject',
'SecretObjectType'
)
'SecretObjectType')

if not is_remove:
if is_identity_credential:
Expand Down
31 changes: 26 additions & 5 deletions src/azure-cli/azure/cli/command_modules/acr/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
cf_acr_runs,
cf_acr_scope_maps,
cf_acr_tokens,
cf_acr_token_credentials
cf_acr_token_credentials,
cf_acr_private_endpoint_connections
)


Expand Down Expand Up @@ -130,15 +131,13 @@ def load_command_table(self, _): # pylint: disable=too-many-statements
acr_scope_map_util = CliCommandType(
operations_tmpl='azure.cli.command_modules.acr.scope_map#{}',
table_transformer=scope_map_output_format,
client_factory=cf_acr_scope_maps,
operation_group='scope_map'
client_factory=cf_acr_scope_maps
)

acr_token_util = CliCommandType(
operations_tmpl='azure.cli.command_modules.acr.token#{}',
table_transformer=token_output_format,
client_factory=cf_acr_tokens,
operation_group='token'
client_factory=cf_acr_tokens
)

acr_token_credential_generate_util = CliCommandType(
Expand All @@ -147,6 +146,11 @@ def load_command_table(self, _): # pylint: disable=too-many-statements
client_factory=cf_acr_token_credentials
)

acr_private_endpoint_connection_util = CliCommandType(
operations_tmpl='azure.cli.command_modules.acr.private_endpoint_connection#{}',
client_factory=cf_acr_private_endpoint_connections
)

with self.command_group('acr', acr_custom_util) as g:
g.command('check-name', 'acr_check_name', table_transformer=None)
g.command('list', 'acr_list')
Expand Down Expand Up @@ -294,3 +298,20 @@ def load_command_table(self, _): # pylint: disable=too-many-statements

with self.command_group('acr token credential', acr_token_credential_generate_util) as g:
g.command('generate', 'acr_token_credential_generate')

with self.command_group('acr private-endpoint-connection', acr_private_endpoint_connection_util,
is_preview=True) as g:
g.command('delete', 'delete')
g.show_command('show', 'show')
g.command('list', 'list_connections')
g.command('approve', 'approve')
g.command('reject', 'reject')

with self.command_group('acr identity', acr_custom_util, is_preview=True) as g:
g.command('show', 'show_identity')
g.command('assign', 'assign_identity')
g.command('remove', 'remove_identity')

with self.command_group('acr encryption', acr_custom_util, is_preview=True) as g:
g.command('show', 'show_encryption')
g.command('rotate-key', "rotate_key")
Loading

0 comments on commit 74c3e5c

Please sign in to comment.