Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/azure-cli/azure/cli/command_modules/acr/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@
- name: Create a managed container registry with writable cache repositories enabled.
text: >
az acr create -n myregistry -g MyResourceGroup --sku Premium --writable-cache-repos enabled
- name: Create a Premium registry encrypted with a customer-managed key in Managed HSM.
text: >
az acr create --name myregistry --resource-group MyResourceGroup --sku Premium --identity myidentity --key-encryption-key https://myhsm.managedhsm.azure.net/keys/mykey
"""

helps['acr credential'] = """
Expand Down Expand Up @@ -1856,14 +1859,21 @@
# region encryption
helps['acr encryption'] = """
type: group
short-summary: Manage container registry encryption
short-summary: Manage customer-managed encryption for a container registry.
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
short-summary: Rotate the customer-managed encryption key for a container registry.
long-summary: The registry must already have customer-managed key encryption enabled. The managed identity must have permission to use the new Azure Key Vault or Managed HSM key. For more information, see http://aka.ms/acr/cmk
examples:
- name: Rotate to a versionless Managed HSM key to enable automatic key rotation.
text: >
az acr encryption rotate-key --name myregistry --resource-group MyResourceGroup --identity myidentity --key-encryption-key https://myhsm.managedhsm.azure.net/keys/mykey
- name: Rotate manually to a specific Azure Key Vault key version.
text: >
az acr encryption rotate-key --name myregistry --resource-group MyResourceGroup --identity myidentity --key-encryption-key https://myvault.vault.azure.net/keys/mykey/00000000000000000000000000000000
"""

helps['acr encryption show'] = """
Expand Down
4 changes: 2 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 @@ -126,7 +126,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements

with self.argument_context('acr create', arg_group="Customer managed key") 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. To enable automated rotation, provide a version-less key uri. For manual rotation, provide a versioned key uri.")
c.argument('key_encryption_key', help="Azure Key Vault or Managed HSM key URI. To enable automated rotation, provide a versionless key URI. For manual rotation, provide a versioned key URI.")

with self.argument_context('acr create') as c:
c.argument('allow_metadata_search', arg_type=get_three_state_flag(), is_preview=True, help="Enable or disable the metadata-search feature for the registry. If not specified, this is set to disabled by default.")
Expand Down Expand Up @@ -555,7 +555,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements
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. To enable automated rotation, provide a version-less key uri. For manual rotation, provide a versioned key uri.")
c.argument('key_encryption_key', help="Azure Key Vault or Managed HSM key URI. To enable automated rotation, provide a versionless key URI. For manual rotation, provide a versioned 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")

with self.argument_context('acr connected-registry') as c:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import unittest
from unittest import mock

from azure.cli.command_modules.acr import custom


class AcrEncryptionTests(unittest.TestCase):

@mock.patch('azure.cli.core.commands.client_factory.get_subscription_id', return_value='subscription-id')
@mock.patch.object(custom, '_ensure_identity_resource_id', return_value='identity-resource-id')
@mock.patch.object(custom, 'resolve_identity_client_id', return_value='identity-client-id')
def test_configure_cmk_preserves_managed_hsm_key_uri(
self, resolve_identity_client_id, ensure_identity_resource_id, get_subscription_id):
key_uri = 'https://myhsm.managedhsm.azure.net/keys/mykey'
key_vault_properties = mock.Mock()
encryption_property = mock.Mock()
resource_identity_type = mock.Mock(user_assigned='UserAssigned')
identity_properties = mock.Mock()
cmd = mock.Mock()
cmd.get_models.side_effect = [
(key_vault_properties, encryption_property),
(resource_identity_type, identity_properties),
]
registry = mock.Mock()

custom._configure_cmk(
cmd,
registry,
'resource-group',
'myidentity',
key_uri)

get_subscription_id.assert_called_once_with(cmd.cli_ctx)
ensure_identity_resource_id.assert_called_once_with(
subscription_id='subscription-id',
resource_group='resource-group',
resource='myidentity')
resolve_identity_client_id.assert_called_once_with(
cmd.cli_ctx,
'identity-resource-id')
key_vault_properties.assert_called_once_with(
key_identifier=key_uri,
identity='identity-client-id')
encryption_property.assert_called_once_with(
status='enabled',
key_vault_properties=key_vault_properties.return_value)
identity_properties.assert_called_once_with(
type='UserAssigned',
user_assigned_identities={'identity-resource-id': {}})
self.assertIs(registry.encryption, encryption_property.return_value)
self.assertIs(registry.identity, identity_properties.return_value)

@mock.patch.object(custom, 'get_registry_by_name')
def test_rotate_key_preserves_managed_hsm_key_uri(self, get_registry_by_name):
registry = mock.Mock()
registry.encryption = mock.Mock()
registry.encryption.key_vault_properties = mock.Mock()
get_registry_by_name.return_value = registry, 'resource-group'
cmd = mock.Mock()
client = mock.Mock()

for key_uri in [
'https://myhsm.managedhsm.azure.net/keys/mykey',
'https://myhsm.managedhsm.azure.net/keys/mykey/00000000000000000000000000000000']:
with self.subTest(key_uri=key_uri):
custom.rotate_key(
cmd,
client,
'myregistry',
key_encryption_key=key_uri,
resource_group_name='resource-group')

self.assertEqual(
registry.encryption.key_vault_properties.key_identifier,
key_uri)

self.assertEqual(client.begin_update.call_count, 2)
client.begin_update.assert_called_with(
'resource-group',
'myregistry',
registry)
Loading