diff --git a/src/azure-cli/azure/cli/command_modules/acr/_constants.py b/src/azure-cli/azure/cli/command_modules/acr/_constants.py index 5f87cda299c..1d1ea2cfe26 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_constants.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_constants.py @@ -15,6 +15,12 @@ USER_ASSIGNED_IDENTITY_RESOURCE_ID_TEMPLATE = '/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity_name}' + +class ConnectedRegistryAuthType(Enum): + SYNC_TOKEN = 'SyncToken' + MANAGED_IDENTITY = 'ManagedIdentity' + + TASK_RESOURCE_TYPE = REGISTRY_RESOURCE_TYPE + '/tasks' TASK_VALID_VSTS_URLS = ['visualstudio.com', 'dev.azure.com'] TASK_RESOURCE_ID_TEMPLATE = '/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.ContainerRegistry/registries/{reg}/tasks/{name}' diff --git a/src/azure-cli/azure/cli/command_modules/acr/_help.py b/src/azure-cli/azure/cli/command_modules/acr/_help.py index 6a0eb168315..d3dfddc740a 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_help.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_help.py @@ -1628,6 +1628,10 @@ helps['acr connected-registry create'] = """ type: command short-summary: Create a connected registry for an Azure Container Registry. +long-summary: | + ManagedIdentity authentication requires --identity and cannot be combined with --parent, --sync-token, or --repository. + ManagedIdentity connected registries must be top-level and cannot have children. + If --auth-type is omitted, SyncToken authentication is used. examples: - name: Create a connected registry in registry mode with access to repos app/hello-world and service/mycomponent. It'll create a sync token and scope-map with the right repo permissions. text: | @@ -1642,6 +1646,11 @@ az acr connected-registry create -r mycloudregistry -n myreadonlyacr -p myconnectedregistry \\ --repository "app/mycomponent" -m ReadOnly -s "0 12 * * *" -w PT4H \\ --client-tokens myTokenName1 myTokenName2 + - name: Create a connected registry that authenticates with its parent using a user-assigned managed identity. + text: | + az acr connected-registry create --registry mycloudregistry --name myconnectedregistry \\ + --auth-type ManagedIdentity \\ + --identity "/subscriptions//resourceGroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/myUserAssignedIdentity" """ helps['acr connected-registry delete'] = """ @@ -1701,6 +1710,10 @@ helps['acr connected-registry update'] = """ type: command short-summary: Update a connected registry for an Azure Container Registry. +long-summary: | + Only one-way migration from SyncToken to ManagedIdentity authentication is supported. + The connected registry must have an Offline connection state before migration. If it is Online, run `az acr connected-registry deactivate` and wait until it is Offline. + Changing the managed identity of a connected registry already using ManagedIdentity authentication is not supported. examples: - name: Update the connected registry client Tokens. text: | @@ -1711,11 +1724,17 @@ text: | az acr connected-registry update --registry mycloudregistry --name myreadonlyacr \\ --sync-schedule "0 12 * * *" --sync-window PT4H + - name: Migrate an offline connected registry from SyncToken to ManagedIdentity authentication. + text: | + az acr connected-registry update --registry mycloudregistry --name myconnectedregistry \\ + --auth-type ManagedIdentity \\ + --identity "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myUserAssignedIdentity" """ helps['acr connected-registry get-settings'] = """ type: command -short-summary: Retrieve information required to activate a connected registry, and creates or rotates the sync token credentials. +short-summary: Retrieve information required to activate a connected registry, optionally generating SyncToken credentials. +long-summary: ManagedIdentity settings do not require a sync token password and do not support --generate-password. examples: - name: Get the settings information required to install a connected registry without the password. text: > @@ -1727,12 +1746,12 @@ helps['acr connected-registry permissions'] = """ type: group -short-summary: Manage the repository permissions accross multiple connected registries. Please see https://aka.ms/acr/connected-registry for more information. +short-summary: Manage the repository permissions across multiple connected registries. Only supported for connected registries configured with SyncToken authentication (output is derived from the sync-token scope map). Please see https://aka.ms/acr/connected-registry for more information. """ helps['acr connected-registry permissions update'] = """ type: command -short-summary: Add and remove repository permissions accross all the necessary connected registry sync scope maps. +short-summary: Add and remove repository permissions across all the necessary connected registry sync scope maps. Only supported for connected registries configured with SyncToken authentication. examples: - name: Add permissions to synchronize images from 'repo1' and 'repo2' to the connected registry 'myconnectedregistry' and its ancestors. text: > @@ -1747,7 +1766,7 @@ helps['acr connected-registry permissions show'] = """ type: command -short-summary: Show the connected registry sync scope map information. +short-summary: Show the connected registry sync scope map information. Only supported for connected registries configured with SyncToken authentication. examples: - name: Show details and attributes of a sync scope map for a connected registry. text: > @@ -1772,6 +1791,7 @@ helps['acr connected-registry install renew-credentials'] = """ type: command short-summary: Retrieve information required to activate a connected registry, and renews the sync token credentials. +long-summary: Only supported for connected registries configured with SyncToken authentication. examples: - name: Set http as the parent protocol, and prints the values in json format required to activate a connected registry and the newly generated sync token credentials. text: > diff --git a/src/azure-cli/azure/cli/command_modules/acr/_params.py b/src/azure-cli/azure/cli/command_modules/acr/_params.py index b21117b5ee5..bf81388be89 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/_params.py +++ b/src/azure-cli/azure/cli/command_modules/acr/_params.py @@ -25,6 +25,7 @@ from ._constants import ( AbacRoleAssignmentMode, + ConnectedRegistryAuthType, REGISTRY_RESOURCE_TYPE, WEBHOOK_RESOURCE_TYPE, REPLICATION_RESOURCE_TYPE, @@ -564,12 +565,12 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('parent_name', options_list=['--parent', '-p'], help='The name of the parent connected registry.') c.argument('repositories', options_list=['--repository'], nargs='+', help='Specify the repositories that need to be sync to the connected registry. It can be in the format [REPO01] [REPO02]...') c.argument('sync_token_name', options_list=['--sync-token'], help='Specifies the sync token used to synchronize the connected registry with its parent. It most have only repo permissions and at least the actions required for its mode. It can include access for multiple repositories.') - c.argument('cleanup', help='It will aslo delete the sync token and the scope map resources.') + c.argument('cleanup', help='Delete the associated sync token and scope map for a connected registry configured with SyncToken authentication. This option has no effect for a connected registry configured with ManagedIdentity authentication. The connected registry is still deleted, but the managed identity and role assignments are retained.') c.argument('no_children', help='Used to remove all children from the list.', action='store_true') c.argument('sync_audit_logs_enabled', options_list=['--audit-logs-enabled'], help='Indicate whether audit log synchronization is enabled. It is enabled by default.', required=False, arg_type=get_three_state_flag(), deprecate_info=c.deprecate(hide=True)) c.argument('parent_protocol', arg_type=get_enum_type(['http', 'https']), options_list=['--parent-protocol'], help='Specify the protocol used to communicate with its parent.', required=True) - c.argument('generate_password', arg_type=get_enum_type(['1', '2']), options_list=['--generate-password'], help='Select which password you want to generate, and it is required to retrieve the password from the sync token.') + c.argument('generate_password', arg_type=get_enum_type(['1', '2']), options_list=['--generate-password'], help='Select which password you want to generate, and it is required to retrieve the password from the sync token. Not supported for a connected registry configured with ManagedIdentity authentication.') with self.argument_context('acr connected-registry create') as c: c.argument('log_level', help='Set the log level for logging on the instance. Accepted log levels are Debug, Information, Warning, Error, and None.', required=False, default="Information") @@ -583,6 +584,8 @@ def load_arguments(self, _): # pylint: disable=too-many-statements help='Indicate whether garbage collection is enabled. It is enabled by default.', arg_type=get_three_state_flag(), required=False, default="true") c.argument('garbage_collection_schedule', options_list=['--gc-schedule'], help='Used to determine garbage collection schedule. Uses cron expression to determine the schedule. If not specified, garbage collection is set to run once a day.', required=False, default="0 0 * * *") + c.argument('identity', help='Resource ID of a user-assigned managed identity to authenticate the connected registry with its parent. Required when --auth-type is ManagedIdentity.') + c.argument('auth_type', arg_type=get_enum_type([e.value for e in ConnectedRegistryAuthType]), options_list=['--auth-type'], help='Authentication type used by the connected registry to sync with its parent. Defaults to SyncToken.') with self.argument_context('acr connected-registry update') as c: c.argument('log_level', help='Set the log level for logging on the instance. Accepted log levels are Debug, Information, Warning, Error, and None.') @@ -600,6 +603,8 @@ def load_arguments(self, _): # pylint: disable=too-many-statements c.argument('garbage_collection_enabled', options_list=['--gc-enabled'], help='Indicate whether garbage collection is enabled. It is enabled by default.', arg_type=get_three_state_flag()) c.argument('garbage_collection_schedule', options_list=['--gc-schedule'], help='Used to determine garbage collection schedule. Uses cron expression to determine the schedule. If not specified, garbage collection is set to run once a day.') + c.argument('identity', help='Resource ID of a user-assigned managed identity. Requires --auth-type ManagedIdentity.') + c.argument('auth_type', arg_type=get_enum_type([ConnectedRegistryAuthType.MANAGED_IDENTITY.value]), options_list=['--auth-type'], help='Target authentication type. Only one-way migration from SyncToken to ManagedIdentity is supported.') with self.argument_context('acr connected-registry permissions') as c: c.argument('add_repos', options_list=['--add'], nargs='*', help='repository permissions to be added to the targeted connected registry and it\'s ancestors sync scope maps. Use the format "--add [REPO1 REPO2 ...]" per flag. ' + repo_valid_actions) diff --git a/src/azure-cli/azure/cli/command_modules/acr/connected_registry.py b/src/azure-cli/azure/cli/command_modules/acr/connected_registry.py index 24cc66efa62..7dc5ca6cb05 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/connected_registry.py +++ b/src/azure-cli/azure/cli/command_modules/acr/connected_registry.py @@ -11,7 +11,9 @@ from azure.cli.core.commands import LongRunningOperation from azure.cli.core.commands.client_factory import get_subscription_id from azure.cli.core.util import user_confirmation +from azure.mgmt.containerregistry.models import ConnectionState, ManagedServiceIdentityType from ._client_factory import cf_acr_tokens, cf_acr_scope_maps, cf_acr_registries +from ._constants import ConnectedRegistryAuthType from ._utils import ( build_token_id, create_default_scope_map, @@ -41,10 +43,37 @@ class ConnectedRegistryModes(Enum): REPOSITORY = "repositories/" GATEWAY = "gateway/" +AUTH_TYPE_SYNC_TOKEN = ConnectedRegistryAuthType.SYNC_TOKEN.value +AUTH_TYPE_MANAGED_IDENTITY = ConnectedRegistryAuthType.MANAGED_IDENTITY.value +MSI_TYPE_USER_ASSIGNED = ManagedServiceIdentityType.USER_ASSIGNED.value +CONNECTION_STATE_OFFLINE = ConnectionState.OFFLINE.value + + +def _get_current_auth_type(connected_registry): + """Return the current auth type ('SyncToken' or 'ManagedIdentity') of a connected registry. + + ``authType`` is the RP's canonical discriminator. Legacy resources predate the field and + deserialize as ``None`` — those are SyncToken by definition. + """ + auth_type = connected_registry.parent.sync_properties.auth_type + # SDK deserializes auth_type as an ``AuthType`` enum; use ``.value`` when available. + auth_type = getattr(auth_type, 'value', auth_type) + return auth_type or AUTH_TYPE_SYNC_TOKEN + + +def _build_user_assigned_identity(cmd, identity_resource_id): + """Wrap a single user-assigned identity resource ID in a ManagedServiceIdentity.""" + ManagedServiceIdentity, UserAssignedIdentity = cmd.get_models('ManagedServiceIdentity', 'UserAssignedIdentity') + return ManagedServiceIdentity( + type=MSI_TYPE_USER_ASSIGNED, + user_assigned_identities={identity_resource_id: UserAssignedIdentity()} + ) + + logger = get_logger(__name__) -def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-many-statements +def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-many-statements, too-many-branches client, registry_name, connected_registry_name, @@ -62,10 +91,33 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m notifications=None, garbage_collection_enabled=None, garbage_collection_schedule=None, + identity=None, + auth_type=None, yes=False): - if bool(sync_token_name) == bool(repositories): - raise CLIError("argument error: either --sync-token or --repository must be provided, but not both.") + is_managed_identity = auth_type == AUTH_TYPE_MANAGED_IDENTITY + if is_managed_identity: + if not identity or identity.isspace(): + raise ArgumentUsageError( + "argument error: --identity is required " + "when --auth-type ManagedIdentity." + ) + if sync_token_name is not None or repositories is not None: + raise ArgumentUsageError( + "argument error: --sync-token and --repository are not applicable when " + "--auth-type ManagedIdentity." + ) + if parent_name is not None: + raise ArgumentUsageError( + "argument error: --parent is not applicable when --auth-type ManagedIdentity." + ) + else: + if identity is not None: + raise ArgumentUsageError( + "argument error: --identity is only applicable with --auth-type ManagedIdentity." + ) + if bool(sync_token_name) == bool(repositories): + raise CLIError("argument error: either --sync-token or --repository must be provided, but not both.") # Check needed since the sync token gateway actions must be at least 5 characters long. if len(connected_registry_name) < 5: raise InvalidArgumentValueError("argument error: Connected registry name must be at least 5 characters long.") @@ -88,6 +140,11 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m if parent_name: try: parent = acr_connected_registry_show(cmd, client, parent_name, registry_name, resource_group_name) + if _get_current_auth_type(parent) == AUTH_TYPE_MANAGED_IDENTITY: + raise ArgumentUsageError( + "A connected registry using ManagedIdentity authentication cannot have children. " + "Choose a SyncToken parent with --parent or omit --parent." + ) connected_registry_list = list(client.list(resource_group_name, registry_name)) family_tree, _ = _get_family_tree(connected_registry_list, None) except ErrorResponseException as ex: @@ -103,7 +160,9 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m _update_ancestor_permissions(cmd, family_tree, resource_group_name, registry_name, parent.id, connected_registry_name, repositories, mode, False) - if sync_token_name: + if is_managed_identity: + sync_token_id = None + elif sync_token_name: sync_token_id = build_token_id(subscription_id, resource_group_name, registry_name, sync_token_name) else: sync_token_id = _create_sync_token(cmd, resource_group_name, registry_name, @@ -122,7 +181,6 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m 'ConnectedRegistry', 'LoggingProperties', 'SyncProperties', 'ParentProperties', 'GarbageCollectionProperties') connected_registry_create_parameters = ConnectedRegistry( - provisioning_state=None, mode=mode, parent=ParentProperties( id=parent.id if parent else None, @@ -130,7 +188,8 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m token_id=sync_token_id, schedule=sync_schedule, message_ttl=sync_message_ttl, - sync_window=sync_window + sync_window=sync_window, + auth_type=AUTH_TYPE_MANAGED_IDENTITY if is_managed_identity else AUTH_TYPE_SYNC_TOKEN, ) ), client_token_ids=client_token_list, @@ -142,7 +201,8 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m enabled=garbage_collection_enabled, schedule=garbage_collection_schedule ), - notifications_list=list(notifications_set) if notifications_set else None + notifications_list=list(notifications_set) if notifications_set else None, + identity=_build_user_assigned_identity(cmd, identity) if is_managed_identity else None, ) try: @@ -154,7 +214,7 @@ def acr_connected_registry_create(cmd, # pylint: disable=too-many-locals, too-m raise CLIError(e) -def acr_connected_registry_update(cmd, # pylint: disable=too-many-locals, too-many-statements +def acr_connected_registry_update(cmd, # pylint: disable=too-many-locals, too-many-statements, too-many-branches client, registry_name, connected_registry_name, @@ -169,13 +229,50 @@ def acr_connected_registry_update(cmd, # pylint: disable=too-many-locals, too-m add_notifications=None, remove_notifications=None, garbage_collection_enabled=None, - garbage_collection_schedule=None): + garbage_collection_schedule=None, + identity=None, + auth_type=None): _, resource_group_name = validate_managed_registry( cmd, registry_name, resource_group_name) subscription_id = get_subscription_id(cmd.cli_ctx) current_connected_registry = acr_connected_registry_show( cmd, client, connected_registry_name, registry_name, resource_group_name) + # Only SyncToken -> ManagedIdentity migration is supported. + identity_update = None + sync_auth_type_update = None + + if auth_type is not None or identity is not None: + if not auth_type: + raise ArgumentUsageError( + "argument error: --auth-type is required when --identity is provided during update." + ) + if auth_type != AUTH_TYPE_MANAGED_IDENTITY: + raise ArgumentUsageError( + "argument error: only migration to --auth-type ManagedIdentity is supported." + ) + if not identity or identity.isspace(): + raise ArgumentUsageError( + "argument error: a non-empty --identity is required " + "when migrating to --auth-type ManagedIdentity." + ) + if _get_current_auth_type(current_connected_registry) == AUTH_TYPE_MANAGED_IDENTITY: + raise ArgumentUsageError( + "Connected registry is already using 'ManagedIdentity' authentication. " + "Same-mode credential rotation is not supported." + ) + current_state = getattr(current_connected_registry, 'connection_state', None) + current_state = getattr(current_state, 'value', current_state) + if current_state != CONNECTION_STATE_OFFLINE: + raise ArgumentUsageError( + "Connected registry must be in '{}' state to migrate authentication mode. " + "Current state is '{}'. Deactivate it first with " + "'az acr connected-registry deactivate' and wait until it is Offline.".format( + CONNECTION_STATE_OFFLINE, current_state) + ) + identity_update = _build_user_assigned_identity(cmd, identity) + sync_auth_type_update = AUTH_TYPE_MANAGED_IDENTITY + # Add or remove from the current client token id list if add_client_token_list is not None: for i, client_token_name in enumerate(add_client_token_list): @@ -233,7 +330,8 @@ def acr_connected_registry_update(cmd, # pylint: disable=too-many-locals, too-m sync_properties=SyncUpdateProperties( schedule=sync_schedule, message_ttl=sync_message_ttl, - sync_window=sync_window + sync_window=sync_window, + auth_type=sync_auth_type_update, ), logging=LoggingProperties( log_level=log_level, @@ -244,7 +342,8 @@ def acr_connected_registry_update(cmd, # pylint: disable=too-many-locals, too-m schedule=garbage_collection_schedule ), client_token_ids=client_token_list, - notifications_list=notifications_list + notifications_list=notifications_list, + identity=identity_update, ) try: @@ -265,15 +364,22 @@ def acr_connected_registry_delete(cmd, resource_group_name=None): _, resource_group_name = validate_managed_registry( cmd, registry_name, resource_group_name) - extraMsg = "" - if not cleanup: - extraMsg = " without cleanup flag enabled" - user_confirmation("Are you sure you want to delete the connected registry '{}' in '{}'{}?".format( - connected_registry_name, registry_name, extraMsg), yes) + try: connected_registry = acr_connected_registry_show( cmd, client, connected_registry_name, registry_name, resource_group_name) + extra_msg = "" + if not cleanup and _get_current_auth_type(connected_registry) == AUTH_TYPE_SYNC_TOKEN: + extra_msg = " without cleanup flag enabled" + user_confirmation("Are you sure you want to delete the connected registry '{}' in '{}'{}?".format( + connected_registry_name, registry_name, extra_msg), yes) result = client.begin_delete(resource_group_name, registry_name, connected_registry_name).result() + if _get_current_auth_type(connected_registry) == AUTH_TYPE_MANAGED_IDENTITY: + if cleanup: + logger.warning( + "'--cleanup' has no effect for connected registry '%s' using ManagedIdentity authentication. " + "The managed identity and role assignments are retained.", connected_registry_name) + return result sync_token = get_token_from_id(cmd, connected_registry.parent.sync_properties.token_id) sync_token_name = sync_token.name sync_scope_map_name = sync_token.scope_map_id.split('/scopeMaps/')[1] @@ -472,7 +578,44 @@ def acr_connected_registry_install_renew_credentials(cmd, '1', yes, resource_group_name) -def acr_connected_registry_get_settings(cmd, +def _resolve_parent_endpoint(connected_registry, parent_protocol): + parent_gateway_endpoint = connected_registry.parent.sync_properties.gateway_endpoint \ + or "" + if connected_registry.parent.id: + parent_endpoint_protocol = parent_protocol + else: + if parent_protocol != "https": + logger.warning("Parent endpoint protocol must be 'https' when parent is a cloud registry.") + parent_endpoint_protocol = "https" + return parent_gateway_endpoint, parent_endpoint_protocol + + +def _build_connected_registry_settings(connected_registry_name, + parent_gateway_endpoint, + parent_endpoint_protocol, + auth_connection_fragment, + auth_env): + connection_string = ( + "ConnectedRegistryName={};".format(connected_registry_name) + + auth_connection_fragment + + "ParentGatewayEndpoint={};".format(parent_gateway_endpoint) + + "ParentEndpointProtocol={}".format(parent_endpoint_protocol) + ) + login_server_placeholder = ( + "" + ) + settings = dict(auth_env) + settings.update({ + "ACR_REGISTRY_CERTIFICATE_VOLUME": "/var/acr/certs", + "ACR_REGISTRY_DATA_VOLUME": "/var/acr/data", + "ACR_REGISTRY_CONNECTION_STRING": connection_string, + "ACR_REGISTRY_LOGIN_SERVER": login_server_placeholder, + }) + return settings + + +def acr_connected_registry_get_settings(cmd, # pylint: disable=too-many-locals client, connected_registry_name, registry_name, @@ -485,6 +628,35 @@ def acr_connected_registry_get_settings(cmd, connected_registry = acr_connected_registry_show( cmd, client, connected_registry_name, registry_name, resource_group_name) + if _get_current_auth_type(connected_registry) == AUTH_TYPE_MANAGED_IDENTITY: + if generate_password: + raise ArgumentUsageError( + "argument error: --generate-password is not applicable for a connected registry " + "configured with ManagedIdentity authentication." + ) + identity = getattr(connected_registry, 'identity', None) + user_assigned = identity.user_assigned_identities if identity else None + if not user_assigned: + raise CLIError( + "Connected registry '{}' is in ManagedIdentity mode but no user-assigned identity is " + "attached.".format(connected_registry_name)) + # exactly one user-assigned identity is expected. + msi_resource_id, msi = next(iter(user_assigned.items())) + client_id = getattr(msi, 'client_id', None) + if not client_id: + raise CLIError( + "Client ID for user-assigned identity '{}' is not populated by the service yet.".format( + msi_resource_id)) + parent_gateway_endpoint, parent_endpoint_protocol = _resolve_parent_endpoint( + connected_registry, parent_protocol) + return _build_connected_registry_settings( + connected_registry_name, + parent_gateway_endpoint, + parent_endpoint_protocol, + auth_connection_fragment="ManagedIdentityClientId={};".format(client_id), + auth_env={"ACR_MANAGED_IDENTITY_RESOURCE_ID": msi_resource_id}, + ) + sync_token_name = connected_registry.parent.sync_properties.token_id.split('/tokens/')[1] if generate_password: user_confirmation("Are you sure you want to generate a new sync token '{}' password{}?".format( @@ -513,31 +685,18 @@ def acr_connected_registry_get_settings(cmd, sync_username = sync_token_name sync_password = "" - parent_gateway_endpoint = connected_registry.parent.sync_properties.gateway_endpoint - if parent_gateway_endpoint is None or parent_gateway_endpoint == '': - parent_gateway_endpoint = "" - parent_id = connected_registry.parent.id - # if parent_id is not none, parent is a connected registry - if parent_id: - parent_endpoint_protocol = parent_protocol - # if parent_id is none, parent is a cloud registry - else: - if parent_protocol != "https": - logger.warning("Parent endpoint protocol must be 'https' when parent is a cloud registry.") - parent_endpoint_protocol = "https" - connected_registry_login_server = "" - connection_string = "ConnectedRegistryName=%s;" % connected_registry_name + \ - "SyncTokenName=%s;SyncTokenPassword=%s;" % (sync_username, sync_password) + \ - "ParentGatewayEndpoint=%s;ParentEndpointProtocol=%s" % (parent_gateway_endpoint, parent_endpoint_protocol) - return { - "SYNC_TOKEN_USER": sync_username, - "SYNC_TOKEN_PASSWORD": sync_password, - "ACR_REGISTRY_CERTIFICATE_VOLUME": "/var/acr/certs", - "ACR_REGISTRY_DATA_VOLUME": "/var/acr/data", - "ACR_REGISTRY_CONNECTION_STRING": connection_string, - "ACR_REGISTRY_LOGIN_SERVER": connected_registry_login_server - } + parent_gateway_endpoint, parent_endpoint_protocol = _resolve_parent_endpoint( + connected_registry, parent_protocol) + return _build_connected_registry_settings( + connected_registry_name, + parent_gateway_endpoint, + parent_endpoint_protocol, + auth_connection_fragment="SyncTokenName={};SyncTokenPassword={};".format(sync_username, sync_password), + auth_env={ + "SYNC_TOKEN_USER": sync_username, + "SYNC_TOKEN_PASSWORD": sync_password, + }, + ) # endregion @@ -624,6 +783,12 @@ def acr_connected_registry_permissions_show(cmd, cmd, registry_name, resource_group_name) connected_registry = acr_connected_registry_show( cmd, client, connected_registry_name, registry_name, resource_group_name) + if _get_current_auth_type(connected_registry) == AUTH_TYPE_MANAGED_IDENTITY: + raise ArgumentUsageError( + "'az acr connected-registry permissions show' is not supported for a connected registry " + "using ManagedIdentity authentication. View the managed identity's Azure role assignments " + "and ABAC conditions to determine its repository permissions." + ) sync_token = get_token_from_id(cmd, connected_registry.parent.sync_properties.token_id) return get_scope_map_from_id(cmd, sync_token.scope_map_id) @@ -653,6 +818,12 @@ def acr_connected_registry_permissions_update(cmd, family_tree, target_connected_registry = _get_family_tree(connected_registry_list, connected_registry_name) if target_connected_registry is None: raise CLIError("Connected registry '{}' doesn't exist.".format(connected_registry_name)) + if _get_current_auth_type(target_connected_registry) == AUTH_TYPE_MANAGED_IDENTITY: + raise ArgumentUsageError( + "'az acr connected-registry permissions update' is not supported for a connected registry " + "using ManagedIdentity authentication. Update the ABAC conditions on the managed identity's " + "Azure role assignments to grant or revoke its repository permissions." + ) # remove repo permissions from connected registry descendants. remove_actions = REPO_SCOPES_BY_MODE[ConnectedRegistryModes.READWRITE.value] diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity.yaml b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity.yaml new file mode 100644 index 00000000000..c99a83dd953 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity.yaml @@ -0,0 +1,1028 @@ +interactions: +- request: + body: '{"location": "eastus", "sku": {"name": "Premium"}, "properties": {"adminUserEnabled": + false, "roleAssignmentMode": "AbacRepositoryPermissions"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + Content-Length: + - '144' + Content-Type: + - application/json + ParameterSetName: + - -n -g -l --sku --role-assignment-mode + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:22.6256643+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"regionalEndpoints":"Disabled","dataEndpointHostNames":[],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1722' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:29 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/5c10bb92-7260-41ae-b356-7be602802f2f + x-ms-ratelimit-remaining-subscription-global-writes: + - '12000' + x-ms-ratelimit-remaining-subscription-writes: + - '800' + x-msedge-ref: + - 'Ref A: 87F98FDB20ED408C94A2121F24B75187 Ref B: SYD281080712062 Ref C: 2026-09-21T04:14:21Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr update + Connection: + - keep-alive + ParameterSetName: + - -n -g --data-endpoint-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:22.6256643+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"regionalEndpoints":"Disabled","dataEndpointHostNames":[],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1722' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:31 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A7426E28EC6249FCABF7A14E59B04334 Ref B: SYD281080711060 Ref C: 2026-09-21T04:14:31Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"dataEndpointEnabled": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr update + Connection: + - keep-alive + Content-Length: + - '45' + Content-Type: + - application/json + ParameterSetName: + - -n -g --data-endpoint-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PATCH + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:32 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/460e6290-5986-475a-ade5-334e498b661a + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: CD2FCDFAD327465BAFE82C0FB980197F Ref B: SYD281080706054 Ref C: 2026-09-21T04:14:32Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity create + Connection: + - keep-alive + ParameterSetName: + - --name -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001?api-version=2024-11-01 + response: + body: + string: '{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001","name":"clitest.rg000001","type":"Microsoft.Resources/resourceGroups","location":"westus","tags":{"product":"azurecli","cause":"automation","test":"test_acr_connectedregistry_managed_identity","date":"2026-09-21T04:14:16Z","module":"acr"},"properties":{"provisioningState":"Succeeded"}}' + headers: + cache-control: + - no-cache + content-length: + - '378' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:33 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 048DF40B5CCD4612B39D2BEB3463A0D1 Ref B: SYD281080711062 Ref C: 2026-09-21T04:14:33Z' + status: + code: 200 + message: OK +- request: + body: '{"location": "westus"}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity create + Connection: + - keep-alive + Content-Length: + - '22' + Content-Type: + - application/json + ParameterSetName: + - --name -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003?api-version=2025-05-31-preview + response: + body: + string: '{"location":"westus","tags":{},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003","name":"cr-mi-id000003","type":"Microsoft.ManagedIdentity/userAssignedIdentities","properties":{"isolationScope":"None","assignmentRestrictions":{"providers":[]},"tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","principalId":"0509fc30-f152-4292-8373-384dcd592828","clientId":"8106ddd1-7697-4a47-9f7f-d66c63d603c6"}}' + headers: + cache-control: + - no-cache + content-length: + - '512' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:37 GMT + expires: + - '-1' + location: + - /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003 + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/26e286d0-2119-40a3-b6ea-8ec0b498187d + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 0E9DE3EF4F67415A9EE325A864F295B8 Ref B: SYD281080708025 Ref C: 2026-09-21T04:14:34Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + ParameterSetName: + - -n -r -g -m --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:38 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 6854B644B3E64C0CA97E641FEC52901A Ref B: SYD281080707025 Ref C: 2026-09-21T04:14:38Z' + status: + code: 200 + message: OK +- request: + body: '{"identity": {"type": "UserAssigned", "userAssignedIdentities": {"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003": + {}}}, "properties": {"garbageCollection": {"enabled": "true", "schedule": "0 + 0 * * *"}, "mode": "readonly", "parent": {"syncProperties": {"schedule": "* + * * * *", "messageTtl": "P2D", "authType": "ManagedIdentity"}}, "logging": {"logLevel": + "Information", "auditLogStatus": "Disabled"}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + Content-Length: + - '513' + Content-Type: + - application/json + ParameterSetName: + - -n -r -g -m --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"0509fc30-f152-4292-8373-384dcd592828","clientId":"8106ddd1-7697-4a47-9f7f-d66c63d603c6"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen","name":"crmiscen","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:40.3062901+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:40.3062901+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"* + * * * *","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Information","auditLogStatus":"Disabled"},"garbageCollection":{"enabled":true,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1281' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:41 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/da28f5de-40ff-4637-bef6-871d4603a53b + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: FF7B35CD1C20470C92D0F48675762BBE Ref B: SYD281080705062 Ref C: 2026-09-21T04:14:40Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:41 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: B75C589C1A004E0C99DAD44790EB2747 Ref B: SYD281080708052 Ref C: 2026-09-21T04:14:41Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"0509fc30-f152-4292-8373-384dcd592828","clientId":"8106ddd1-7697-4a47-9f7f-d66c63d603c6"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen","name":"crmiscen","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:40.3062901+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:40.3062901+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"* + * * * *","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Information","auditLogStatus":"Disabled"},"garbageCollection":{"enabled":true,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1281' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:42 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/3dd1376c-95e2-40cd-be9a-80563257692f + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 418A6970DDC049469D284F95EBF38833 Ref B: SYD281080711023 Ref C: 2026-09-21T04:14:42Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:44 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: AEA3137A142B425480285A240A2DAC00 Ref B: SYD281080705034 Ref C: 2026-09-21T04:14:43Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:44 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: F90DC6DF065F42A0B9882AA7B52000B4 Ref B: SYD281080708060 Ref C: 2026-09-21T04:14:44Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"0509fc30-f152-4292-8373-384dcd592828","clientId":"8106ddd1-7697-4a47-9f7f-d66c63d603c6"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen","name":"crmiscen","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:40.3062901+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:40.3062901+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"* + * * * *","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Information","auditLogStatus":"Disabled"},"garbageCollection":{"enabled":true,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1281' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:45 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/b701581e-392a-4d28-a084-ff362698c121 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 966757DC54E1405B88EED49D10A4A25B Ref B: SYD281080711031 Ref C: 2026-09-21T04:14:45Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:46 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0C16240A62A54EB490A3B1A84EC266D1 Ref B: SYD281080709040 Ref C: 2026-09-21T04:14:46Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:47 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: CBFA27AC49AD441D91C67250F02BF598 Ref B: SYD281080707029 Ref C: 2026-09-21T04:14:47Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"0509fc30-f152-4292-8373-384dcd592828","clientId":"8106ddd1-7697-4a47-9f7f-d66c63d603c6"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen","name":"crmiscen","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:40.3062901+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:40.3062901+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"* + * * * *","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Information","auditLogStatus":"Disabled"},"garbageCollection":{"enabled":true,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1281' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:47 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/95e8caa6-d44b-49de-8cf0-b873308969b2 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 39036F8360BB4D04ACE5B5B286EC4530 Ref B: SYD281080709060 Ref C: 2026-09-21T04:14:48Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -r -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmiscen?api-version=2026-09-01-preview + response: + body: + string: '' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:14:48 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/eb200d07-acf4-4f6d-8222-9779354d936e + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: AA2DEBBF0BCF4CFFB2851E215FE7E7AD Ref B: SYD281080705062 Ref C: 2026-09-21T04:14:48Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:14:22.6256643+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:14:32.6858052+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:14:22.6256643Z","provisioningState":"Deleting","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:14:29.9778722+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:14:29.9779109+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1757' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:14:49 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-fc616d77-b572-11f1-bdd4-3cefa50a58cc?api-version=2026-09-01-preview&t=639255608899252598&c=MIIHwzCCBqugAwIBAgIQO9vjerLJyzCAZGOG8qnuujANBgkqhkiG9w0BAQsFADA1MTMwMQYDVQQDEypDQ01FIEcxIFRMUyBSU0EgMjA0OCBTSEEyNTYgMjA0OSBDVVMgQ0EgMDEwHhcNMjYwOTE3MTkyNzU0WhcNMjYxMjEzMDEyNzU0WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOH7XcOFB9oBlttbwx8AirjT-trX0XvGg-qTsZnfCNKSBKRmEGUNPWfYKFgDpx0AZwfOinDzB58zssD8uZb2jeDqfJuiR1vqsOBWntnOkwx0IgWzw_pbET-L7lO_ZYW2-ec3c5ZewHiy0Jr51TL2zNtCadpjfB2g2RkKJY_5Zgyqgccwx0LvPgj81bdByhSFWtd49llL8NuFYWjo3Fk7HmsitrM-T8Z3xgac37X6nC2PTsQFiO6h917Etzgh-KBeYYfZiOTF9hHnetiX5px_9XecvBma56vHFyzqoF4VpkESo5tWkT_beymCu5gy2ngynn3SNDYyVgZXGrEn4V_OKM0CAwEAAaOCBMIwggS-MIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFLXKU9erjRhgRqjwHfGKduIH8QgZMB8GA1UdIwQYMBaAFPzkWgovhQ7nRLkHc3jg1EQHohkRMIIBygYDVR0fBIIBwTCCAb0wb6BtoGuGaWh0dHA6Ly9wcmltYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZW50cmFsdXMvY3Jscy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS84MS9jdXJyZW50LmNybDBxoG-gbYZraHR0cDovL3NlY29uZGFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvY2VudHJhbHVzL2NybHMvY2NtZWNlbnRyYWx1c3BraS9jY21lY2VudHJhbHVzaWNhMDEvODEvY3VycmVudC5jcmwwYKBeoFyGWmh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9jZW50cmFsdXMvY3Jscy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS84MS9jdXJyZW50LmNybDB1oHOgcYZvaHR0cDovL2NjbWVjZW50cmFsdXNwa2kuY2VudHJhbHVzLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWNlbnRyYWx1c2ljYTAxLzgxL2N1cnJlbnQuY3JsMIIBzwYIKwYBBQUHAQEEggHBMIIBvTByBggrBgEFBQcwAoZmaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2NlbnRyYWx1cy9jYWNlcnRzL2NjbWVjZW50cmFsdXNwa2kvY2NtZWNlbnRyYWx1c2ljYTAxL2NlcnQuY2VyMHQGCCsGAQUFBzAChmhodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZW50cmFsdXMvY2FjZXJ0cy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS9jZXJ0LmNlcjBjBggrBgEFBQcwAoZXaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2NlbnRyYWx1cy9jYWNlcnRzL2NjbWVjZW50cmFsdXNwa2kvY2NtZWNlbnRyYWx1c2ljYTAxL2NlcnQuY2VyMGwGCCsGAQUFBzAChmBodHRwOi8vY2NtZWNlbnRyYWx1c3BraS5jZW50cmFsdXMucGtpLmNvcmUud2luZG93cy5uZXQvY2VydGlmaWNhdGVBdXRob3JpdGllcy9jY21lY2VudHJhbHVzaWNhMDEwDQYJKoZIhvcNAQELBQADggEBAEdUznjVdYbUtxHD93flzOpv9itmdLU-P-i-amvvUBn1ESE_kJadN1MNgEM7wepiASPBur_kdjFJFZ5QdmL9EfoQmFlXLFS-v1qgMBh2uK-7Kx5nCPVe7MfrPZyaDtWWZoKQ1ku_7opeRh0t5mG0O3vQdmu-gxm9jX2bOhHTHW_uA9yYnskYrIv0kyqah1mv5zf85_XKMRSd592hVfIL4O9kUoKFjYKYWROv0MDSHRzOr2h9LjtoXGtDVpaGhgXaw6SQLRfR9piqIFxVYxpsgwP30Cdlvv9Vz-bZEpoPLRZc4_cpvPp6ZaWJSQgQNnoHo1QDfwAPoEEjmUxvRB06lrI&s=2UFdjQhrw7dbU_YbAPIlakEUWMpmD3ffH92PGMWi4HxnSRkWA_LE4AcQAL8RC1O9NwrkbHKz59s9ySWNf51cyproqW40Nuf38s3o_xOlFzE_qBl_iUxqkLGc3VigaujpaYiA-JJDWVrQZDKIieVBEYxkMjzLMnRfunVCn8ysfcFpfD9-A3vTWcYcWxg3ilgyVDrl0knPhesmTw0cEbnSvieMnb41W7oLsQIP7RB_uEqHj587nZbNeeI9FWI_RQBhEsuVbgP5fXMUbxm6TC1taFY2PRLASVJ6rAi2JsIdNYG22twYwVd0WxubEsFM0T06TzQmQn6kC9B63WoEVJAeWg&h=ioqda8ion8RijFe0JMrfWVlfO4fl_M4D-atK4t6SyIM + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/f1a2ac6d-09a5-482f-8c15-869986b81fa1 + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 2F725A8717F54D2295B41C5D62980919 Ref B: SYD281080707052 Ref C: 2026-09-21T04:14:49Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-fc616d77-b572-11f1-bdd4-3cefa50a58cc?api-version=2026-09-01-preview&t=639255608899252598&c=MIIHwzCCBqugAwIBAgIQO9vjerLJyzCAZGOG8qnuujANBgkqhkiG9w0BAQsFADA1MTMwMQYDVQQDEypDQ01FIEcxIFRMUyBSU0EgMjA0OCBTSEEyNTYgMjA0OSBDVVMgQ0EgMDEwHhcNMjYwOTE3MTkyNzU0WhcNMjYxMjEzMDEyNzU0WjBAMT4wPAYDVQQDEzVhc3luY29wZXJhdGlvbnNpZ25pbmdjZXJ0aWZpY2F0ZS5tYW5hZ2VtZW50LmF6dXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOH7XcOFB9oBlttbwx8AirjT-trX0XvGg-qTsZnfCNKSBKRmEGUNPWfYKFgDpx0AZwfOinDzB58zssD8uZb2jeDqfJuiR1vqsOBWntnOkwx0IgWzw_pbET-L7lO_ZYW2-ec3c5ZewHiy0Jr51TL2zNtCadpjfB2g2RkKJY_5Zgyqgccwx0LvPgj81bdByhSFWtd49llL8NuFYWjo3Fk7HmsitrM-T8Z3xgac37X6nC2PTsQFiO6h917Etzgh-KBeYYfZiOTF9hHnetiX5px_9XecvBma56vHFyzqoF4VpkESo5tWkT_beymCu5gy2ngynn3SNDYyVgZXGrEn4V_OKM0CAwEAAaOCBMIwggS-MIGdBgNVHSAEgZUwgZIwDAYKKwYBBAGCN3sBATBmBgorBgEEAYI3ewICMFgwVgYIKwYBBQUHAgIwSh5IADMAMwBlADAAMQA5ADIAMQAtADQAZAA2ADQALQA0AGYAOABjAC0AYQAwADUANQAtADUAYgBkAGEAZgBmAGQANQBlADMAMwBkMAwGCisGAQQBgjd7AwIwDAYKKwYBBAGCN3sEAjAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFLXKU9erjRhgRqjwHfGKduIH8QgZMB8GA1UdIwQYMBaAFPzkWgovhQ7nRLkHc3jg1EQHohkRMIIBygYDVR0fBIIBwTCCAb0wb6BtoGuGaWh0dHA6Ly9wcmltYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZW50cmFsdXMvY3Jscy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS84MS9jdXJyZW50LmNybDBxoG-gbYZraHR0cDovL3NlY29uZGFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvY2VudHJhbHVzL2NybHMvY2NtZWNlbnRyYWx1c3BraS9jY21lY2VudHJhbHVzaWNhMDEvODEvY3VycmVudC5jcmwwYKBeoFyGWmh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9jZW50cmFsdXMvY3Jscy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS84MS9jdXJyZW50LmNybDB1oHOgcYZvaHR0cDovL2NjbWVjZW50cmFsdXNwa2kuY2VudHJhbHVzLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWNlbnRyYWx1c2ljYTAxLzgxL2N1cnJlbnQuY3JsMIIBzwYIKwYBBQUHAQEEggHBMIIBvTByBggrBgEFBQcwAoZmaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2NlbnRyYWx1cy9jYWNlcnRzL2NjbWVjZW50cmFsdXNwa2kvY2NtZWNlbnRyYWx1c2ljYTAxL2NlcnQuY2VyMHQGCCsGAQUFBzAChmhodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZW50cmFsdXMvY2FjZXJ0cy9jY21lY2VudHJhbHVzcGtpL2NjbWVjZW50cmFsdXNpY2EwMS9jZXJ0LmNlcjBjBggrBgEFBQcwAoZXaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2NlbnRyYWx1cy9jYWNlcnRzL2NjbWVjZW50cmFsdXNwa2kvY2NtZWNlbnRyYWx1c2ljYTAxL2NlcnQuY2VyMGwGCCsGAQUFBzAChmBodHRwOi8vY2NtZWNlbnRyYWx1c3BraS5jZW50cmFsdXMucGtpLmNvcmUud2luZG93cy5uZXQvY2VydGlmaWNhdGVBdXRob3JpdGllcy9jY21lY2VudHJhbHVzaWNhMDEwDQYJKoZIhvcNAQELBQADggEBAEdUznjVdYbUtxHD93flzOpv9itmdLU-P-i-amvvUBn1ESE_kJadN1MNgEM7wepiASPBur_kdjFJFZ5QdmL9EfoQmFlXLFS-v1qgMBh2uK-7Kx5nCPVe7MfrPZyaDtWWZoKQ1ku_7opeRh0t5mG0O3vQdmu-gxm9jX2bOhHTHW_uA9yYnskYrIv0kyqah1mv5zf85_XKMRSd592hVfIL4O9kUoKFjYKYWROv0MDSHRzOr2h9LjtoXGtDVpaGhgXaw6SQLRfR9piqIFxVYxpsgwP30Cdlvv9Vz-bZEpoPLRZc4_cpvPp6ZaWJSQgQNnoHo1QDfwAPoEEjmUxvRB06lrI&s=2UFdjQhrw7dbU_YbAPIlakEUWMpmD3ffH92PGMWi4HxnSRkWA_LE4AcQAL8RC1O9NwrkbHKz59s9ySWNf51cyproqW40Nuf38s3o_xOlFzE_qBl_iUxqkLGc3VigaujpaYiA-JJDWVrQZDKIieVBEYxkMjzLMnRfunVCn8ysfcFpfD9-A3vTWcYcWxg3ilgyVDrl0knPhesmTw0cEbnSvieMnb41W7oLsQIP7RB_uEqHj587nZbNeeI9FWI_RQBhEsuVbgP5fXMUbxm6TC1taFY2PRLASVJ6rAi2JsIdNYG22twYwVd0WxubEsFM0T06TzQmQn6kC9B63WoEVJAeWg&h=ioqda8ion8RijFe0JMrfWVlfO4fl_M4D-atK4t6SyIM + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:14:51 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-fc616d77-b572-11f1-bdd4-3cefa50a58cc?api-version=2026-09-01-preview&t=639255608915655641&c=MIIHlTCCBn2gAwIBAgIRAP3gA1NTVfsyY1OAzEH6ZxgwDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgV1VTMiBDQSAwMTAeFw0yNjA4MTcwMzUwMzRaFw0yNzAyMTIwOTUwMzRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4QdyZCaJJyeTiLaFPtWJfrFjQBvFiPuzXEv1RYUnOVbG6CgM9-zAjE6VqzzH_ry3ylc1gfGz6trnOm36FC95XZN2cCXp9y49dBX5ARtbkqOb5BHj5WIXttGYC8azrRlvpPY-UgoTrxrODNYnd9zPdmWFTt8eiVOabmtu8YkeC5xQbAfStgY-cSF67cM163I2m0lUmMRhXAoURoP8LYqW8LPszEPUm35qa6W0XcEfar_boQxw4ZdhrhAO_JSNzOmKlvArod48lGW9Qo67YUrtSxaxhZLN-ToHXgM2BXkkOkxuLlfF-zewr3Hc0ZK_XonevTH-HqtYfak-VOdgLwwwQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQUMwWFFADYJuZjpCje-R5vqszDG70wHwYDVR0jBBgwFoAUrONy-gOyc549lcjvh1uu3Ruh7WgwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkzL2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC93ZXN0dXMyL2NybHMvY2NtZXdlc3R1czJwa2kvY2NtZXdlc3R1czJpY2EwMS85My9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkzL2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZXdlc3R1czJwa2kud2VzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWV3ZXN0dXMyaWNhMDEvOTMvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY2FjZXJ0cy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21ld2VzdHVzMnBraS53ZXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZXdlc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAfdst7PXa3ogyQLF7Jy4O_dGeSpqDceWxzIbo4NIpZfZMInuRZt6N1cZ17JzQwO9wpT3dbvQrW_9Chfhc9K26kB7skQlG9nV6CIaJ5LroI00qr85tOPRcMbzSa_LwIM_1WhqUAbC1vt42bKM4cgC_QniX7bfhwBKQ7zUjh4Fstu-6lYJzztVawXpnNMYNceUEljzwL2p7jhz2ReKQafSIStD7cREW2DUKEw0nW492Ro2Eb8rMaVqMGpcq__nFurDqDstzrSOzcc76ZsENCHFmj_X5HdtdrvHDESbNm8n4LAaZi15lQlMTGFLJdEx8Ck-obWaoY0XEIqJDE2uMyZfZ7Q&s=ZH4BzBW4H-xDNBzf01Tp6osFNLBWE_NYML80OMZ8mZA7KewSeBCC3G3dRE1030cIhuqqwH8iJi1guaXnnBGLmDzFYYM6L96sNlC9rOnMlvm0u5pfplSlnDnpLfh2ql9tsOanQJvgmJYd-A13C3m28wi9xS9VIsRZWPPCfntDqjDJbd-eF7c5qIAJ8eYab2XejJOaPjr1iNJUyF4wseKkNo0fif39ZqQNTEzwMhv99A1JWQURHBBeWn3ypSYolG00pDgTRJZDDYsXFdmeY7HQGflnLgv0yyT-3BxB_WkzefmNGf0esZcKJZnjlYbayGpQXXuwmyEFSOfmianyMddU_g&h=PNN87rltqhO5Jm3CUaRT8juK-4-zVvT1j14WHvQet0M + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiacentral/ccacbe81-a445-4182-aaf1-39089737e2fd + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 241FA77D1F024ECCB96023467A77FCFA Ref B: SYD281080712036 Ref C: 2026-09-21T04:14:50Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-fc616d77-b572-11f1-bdd4-3cefa50a58cc?api-version=2026-09-01-preview&t=639255608915655641&c=MIIHlTCCBn2gAwIBAgIRAP3gA1NTVfsyY1OAzEH6ZxgwDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgV1VTMiBDQSAwMTAeFw0yNjA4MTcwMzUwMzRaFw0yNzAyMTIwOTUwMzRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz4QdyZCaJJyeTiLaFPtWJfrFjQBvFiPuzXEv1RYUnOVbG6CgM9-zAjE6VqzzH_ry3ylc1gfGz6trnOm36FC95XZN2cCXp9y49dBX5ARtbkqOb5BHj5WIXttGYC8azrRlvpPY-UgoTrxrODNYnd9zPdmWFTt8eiVOabmtu8YkeC5xQbAfStgY-cSF67cM163I2m0lUmMRhXAoURoP8LYqW8LPszEPUm35qa6W0XcEfar_boQxw4ZdhrhAO_JSNzOmKlvArod48lGW9Qo67YUrtSxaxhZLN-ToHXgM2BXkkOkxuLlfF-zewr3Hc0ZK_XonevTH-HqtYfak-VOdgLwwwQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQUMwWFFADYJuZjpCje-R5vqszDG70wHwYDVR0jBBgwFoAUrONy-gOyc549lcjvh1uu3Ruh7WgwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkzL2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC93ZXN0dXMyL2NybHMvY2NtZXdlc3R1czJwa2kvY2NtZXdlc3R1czJpY2EwMS85My9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkzL2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZXdlc3R1czJwa2kud2VzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWV3ZXN0dXMyaWNhMDEvOTMvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY2FjZXJ0cy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21ld2VzdHVzMnBraS53ZXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZXdlc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAfdst7PXa3ogyQLF7Jy4O_dGeSpqDceWxzIbo4NIpZfZMInuRZt6N1cZ17JzQwO9wpT3dbvQrW_9Chfhc9K26kB7skQlG9nV6CIaJ5LroI00qr85tOPRcMbzSa_LwIM_1WhqUAbC1vt42bKM4cgC_QniX7bfhwBKQ7zUjh4Fstu-6lYJzztVawXpnNMYNceUEljzwL2p7jhz2ReKQafSIStD7cREW2DUKEw0nW492Ro2Eb8rMaVqMGpcq__nFurDqDstzrSOzcc76ZsENCHFmj_X5HdtdrvHDESbNm8n4LAaZi15lQlMTGFLJdEx8Ck-obWaoY0XEIqJDE2uMyZfZ7Q&s=ZH4BzBW4H-xDNBzf01Tp6osFNLBWE_NYML80OMZ8mZA7KewSeBCC3G3dRE1030cIhuqqwH8iJi1guaXnnBGLmDzFYYM6L96sNlC9rOnMlvm0u5pfplSlnDnpLfh2ql9tsOanQJvgmJYd-A13C3m28wi9xS9VIsRZWPPCfntDqjDJbd-eF7c5qIAJ8eYab2XejJOaPjr1iNJUyF4wseKkNo0fif39ZqQNTEzwMhv99A1JWQURHBBeWn3ypSYolG00pDgTRJZDDYsXFdmeY7HQGflnLgv0yyT-3BxB_WkzefmNGf0esZcKJZnjlYbayGpQXXuwmyEFSOfmianyMddU_g&h=PNN87rltqhO5Jm3CUaRT8juK-4-zVvT1j14WHvQet0M + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:15:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/4ddfaf1a-a9ff-449c-8129-d4b44bf9b9be + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 76A4F0F94C8F40B0B90696D0E3AC3668 Ref B: SYD281080709029 Ref C: 2026-09-21T04:15:02Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - identity delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --name -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003?api-version=2025-05-31-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:15:07 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/westus/6f08f0ed-fac5-483e-bb81-5968abb564db + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: BDBDA738ED194CDFBB390501ABF0EAC9 Ref B: SYD281080706029 Ref C: 2026-09-21T04:15:03Z' + status: + code: 200 + message: OK +version: 1 diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity_migration.yaml b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity_migration.yaml new file mode 100644 index 00000000000..fa31649f39e --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/recordings/test_acr_connectedregistry_managed_identity_migration.yaml @@ -0,0 +1,1643 @@ +interactions: +- request: + body: '{"location": "eastus", "sku": {"name": "Premium"}, "properties": {"adminUserEnabled": + false, "roleAssignmentMode": "AbacRepositoryPermissions"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr create + Connection: + - keep-alive + Content-Length: + - '144' + Content-Type: + - application/json + ParameterSetName: + - -n -g -l --sku --role-assignment-mode + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:39.2175714+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"regionalEndpoints":"Disabled","dataEndpointHostNames":[],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1722' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:46 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/289d5df1-afbe-426b-bc3c-ea492d4c09a3 + x-ms-ratelimit-remaining-subscription-global-writes: + - '12000' + x-ms-ratelimit-remaining-subscription-writes: + - '800' + x-msedge-ref: + - 'Ref A: 100EA8BECD79493F9081120BCEAC5FAC Ref B: SYD281080705029 Ref C: 2026-09-21T04:40:37Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr update + Connection: + - keep-alive + ParameterSetName: + - -n -g --data-endpoint-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:39.2175714+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":false,"regionalEndpoints":"Disabled","dataEndpointHostNames":[],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1722' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:47 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: AE95ACD4CB1E4E2E9E17F2E1DE4E5D1C Ref B: SYD281080710025 Ref C: 2026-09-21T04:40:47Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"dataEndpointEnabled": true}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr update + Connection: + - keep-alive + Content-Length: + - '45' + Content-Type: + - application/json + ParameterSetName: + - -n -g --data-endpoint-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PATCH + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:50 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiasoutheast/88f7a069-737f-46fd-9c60-a500c8363d96 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: BF2E1CEA16CA494B916209D29FCA3563 Ref B: SYD281080708036 Ref C: 2026-09-21T04:40:48Z' + status: + code: 200 + message: OK +- request: + body: '{"location": "eastus"}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity create + Connection: + - keep-alive + Content-Length: + - '22' + Content-Type: + - application/json + ParameterSetName: + - -n -g -l + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003?api-version=2025-05-31-preview + response: + body: + string: '{"location":"eastus","tags":{},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003","name":"cr-mi-id000003","type":"Microsoft.ManagedIdentity/userAssignedIdentities","properties":{"isolationScope":"None","assignmentRestrictions":{"providers":[]},"tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}' + headers: + cache-control: + - no-cache + content-length: + - '512' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:54 GMT + expires: + - '-1' + location: + - /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003 + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/e2e8fc7c-0a6e-4e4a-b1c2-4d8e14e30b1d + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 87D08F9630494F8BA5749EADB190126D Ref B: SYD281080708034 Ref C: 2026-09-21T04:40:52Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:56 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A76ADA3D9AF849B39F232E86E6783D50 Ref B: SYD281080712036 Ref C: 2026-09-21T04:40:56Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"error":{"code":"ResourceNotFound","message":"The resource crmigration + could not be found."},"status":"Failed"}' + headers: + api-supported-versions: + - 2019-05-01-preview, 2020-11-01-preview, 2021-06-01-preview, 2021-08-01-preview, + 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, 2023-01-01-preview, 2023-06-01-preview, + 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, 2024-01-01-preview, 2024-11-01-preview, + 2025-03-01-preview, 2025-04-01, 2025-05-01-preview, 2025-06-01-preview, 2025-09-01-preview, + 2025-11-01, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, 2026-09-01-preview, + 2026-11-01 + cache-control: + - no-cache + content-length: + - '112' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:57 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/482b32ff-dd6d-42c1-b326-7a194090b1f3 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 4F71C46ED37E49A8ACF11AC3BFB75429 Ref B: SYD281080705034 Ref C: 2026-09-21T04:40:57Z' + status: + code: 404 + message: Not Found +- request: + body: '{"properties": {"actions": ["repositories/hello-world/content/read", "repositories/hello-world/metadata/read", + "gateway/crmigration/config/read", "gateway/crmigration/config/write", "gateway/crmigration/message/read", + "gateway/crmigration/message/write"], "description": "Created by connected registry + sync token: crmigration"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + Content-Length: + - '328' + Content-Type: + - application/json + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/scopeMaps","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:58.9997153+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:58.9997153+00:00"},"properties":{"description":"Created + by connected registry sync token: crmigration","type":"UserDefined","creationDate":"2026-09-21T04:40:59.0223319+00:00","provisioningState":"Succeeded","actions":["repositories/hello-world/content/read","repositories/hello-world/metadata/read","gateway/crmigration/config/read","gateway/crmigration/config/write","gateway/crmigration/message/read","gateway/crmigration/message/write"]}}' + headers: + api-supported-versions: + - 2019-05-01-preview, 2020-11-01-preview, 2021-06-01-preview, 2021-08-01-preview, + 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, 2023-01-01-preview, 2023-06-01-preview, + 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, 2024-01-01-preview, 2024-11-01-preview, + 2025-03-01-preview, 2025-04-01, 2025-05-01-preview, 2025-06-01-preview, 2025-09-01-preview, + 2025-11-01, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, 2026-09-01-preview, + 2026-11-01 + cache-control: + - no-cache + content-length: + - '911' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:58 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/fb5f8ec9-d918-4820-b927-e55271510d51 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 7935BC7EC4674E138957717A7F1F962C Ref B: SYD281080712036 Ref C: 2026-09-21T04:40:58Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"scopeMapId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration", + "status": "enabled"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + Content-Length: + - '222' + Content-Type: + - application/json + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tokens","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:59.7573903+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:59.7573903+00:00"},"properties":{"creationDate":"2026-09-21T04:40:59.7950047+00:00","provisioningState":"Creating","scopeMapId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration","credentials":{"passwords":[]},"status":"enabled"}}' + headers: + api-supported-versions: + - 2019-05-01-preview, 2020-11-01-preview, 2021-06-01-preview, 2021-08-01-preview, + 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, 2023-01-01-preview, 2023-06-01-preview, + 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, 2024-01-01-preview, 2024-11-01-preview, + 2025-03-01-preview, 2025-04-01, 2025-05-01-preview, 2025-06-01-preview, 2025-09-01-preview, + 2025-11-01, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, 2026-09-01-preview, + 2026-11-01 + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration/operationStatuses/token-a247ff8e-b576-11f1-b229-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624599136421&c=MIIHlTCCBn2gAwIBAgIRAN0yZzL8aR42UZysboj3ciowDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgRVVTMiBDQSAwMTAeFw0yNjA4MTQwMDQwMTRaFw0yNzAyMDkwNjQwMTRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzoSOkVR7MNj87TdZrq2tsL7eEWBZ1UxYUjlHs2t1x6Xn31o-6e5yM1I79Xw17HpG_ZRC01sH0DmLucuBF6EGQR50aTJ6mx22HrEe4YQhQiTieYabApNFEW7C1Z3sqhwTVaWGvV9-nw9anTx1HztS5s2jjMeJoebstq-wBIvYIOyM7hj12vYY5vdXTn9Sask3V8S3KBxdPpOFhQ5pKF6CgT-fQ9-scbzgeKeWuPXZTO0EeH02xAsj1c-lki5VGv0RewzD2beJxGO1-CxJFOfH9H3UnlZMKLg6kT-aBTn6RuYVuLJoMYYC-eHbYtahA3x5r3yutNG8gegIMlLlcdTGAQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQU7naFfTwmNksX70OjHOYQPsR55KIwHwYDVR0jBBgwFoAU_Ow-26p8H4IeBbihBvlD5wKzCrkwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9lYXN0dXMyL2NybHMvY2NtZWVhc3R1czJwa2kvY2NtZWVhc3R1czJpY2EwMS8zOS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZWVhc3R1czJwa2kuZWFzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWVlYXN0dXMyaWNhMDEvMzkvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY2FjZXJ0cy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21lZWFzdHVzMnBraS5lYXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWVhc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAJrRoJWjIzsymA0Vpio4e2hRDOWlG5PpWmWos3Gflt8XcQwRsU-vvdeWk-uT-wHYn52846N5Ue5cbvM8NV-labOA852VL2mtuHnz7bkkRfWTlP-tB-JYDS8l0yGcTENq-UNlakbleLgtfD-Qr09l853jhegiUP3vJKLXMCFF1C2maSNhwZg1MlrEswNSPzRH0Xj9q0-487lH42RncuRXCIqd8ljf1_8v-IXMl6WtDdQDYjQE_s-OHN0BNXt0t4wTd5ikeG6NCH2SHC2wB-PchAiE5P4oHK6Vx3M0q3TEexP11Up6I9ksnpNBw256ZKPa0pX3urxLa215fDhtScA9RzA&s=OcFQKnISu4MoxtO9I1iGTNbT2srXy2EVSM1ULPFlzodZ82AfSZWqAhVoV4pzyEe4DibUPbBl1Q9u-3Hv2xKGIQhXND8pd-tpXknmRTjLinzTge15V4xQbP8Ct20wrf8KEFv3Dj8Mlhuiu10TJGskbuvrAg3DfmnDMUtoYnrT4yk8VEI44Y-aQMT4u_QYk65kQBnnSq3ZODwTV3Wq1RV7mtKCkGsqucV-1NhpF0-NI6MEdJWTiY-rhgKFbl8xl66_8OUjQezfdC6a0hLmqGGOxCEGEHAGRsA5bqzXfr2zcDwpGw9UaEoLLYdFoklQstSBVCn5HBrI1yZc5ikSHAKbNg&h=iabC062MiIDAEIu0nnddLgasL3hceI3HvtCxqsUOl7Q + cache-control: + - no-cache + content-length: + - '813' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:40:59 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/d7edc53a-b63b-431b-ab27-652f6641cd66 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: D6B2F7549BFF44898C29C06992E025DE Ref B: SYD281080710060 Ref C: 2026-09-21T04:40:59Z' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration/operationStatuses/token-a247ff8e-b576-11f1-b229-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624599136421&c=MIIHlTCCBn2gAwIBAgIRAN0yZzL8aR42UZysboj3ciowDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgRVVTMiBDQSAwMTAeFw0yNjA4MTQwMDQwMTRaFw0yNzAyMDkwNjQwMTRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzoSOkVR7MNj87TdZrq2tsL7eEWBZ1UxYUjlHs2t1x6Xn31o-6e5yM1I79Xw17HpG_ZRC01sH0DmLucuBF6EGQR50aTJ6mx22HrEe4YQhQiTieYabApNFEW7C1Z3sqhwTVaWGvV9-nw9anTx1HztS5s2jjMeJoebstq-wBIvYIOyM7hj12vYY5vdXTn9Sask3V8S3KBxdPpOFhQ5pKF6CgT-fQ9-scbzgeKeWuPXZTO0EeH02xAsj1c-lki5VGv0RewzD2beJxGO1-CxJFOfH9H3UnlZMKLg6kT-aBTn6RuYVuLJoMYYC-eHbYtahA3x5r3yutNG8gegIMlLlcdTGAQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQU7naFfTwmNksX70OjHOYQPsR55KIwHwYDVR0jBBgwFoAU_Ow-26p8H4IeBbihBvlD5wKzCrkwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9lYXN0dXMyL2NybHMvY2NtZWVhc3R1czJwa2kvY2NtZWVhc3R1czJpY2EwMS8zOS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZWVhc3R1czJwa2kuZWFzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWVlYXN0dXMyaWNhMDEvMzkvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY2FjZXJ0cy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21lZWFzdHVzMnBraS5lYXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWVhc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAJrRoJWjIzsymA0Vpio4e2hRDOWlG5PpWmWos3Gflt8XcQwRsU-vvdeWk-uT-wHYn52846N5Ue5cbvM8NV-labOA852VL2mtuHnz7bkkRfWTlP-tB-JYDS8l0yGcTENq-UNlakbleLgtfD-Qr09l853jhegiUP3vJKLXMCFF1C2maSNhwZg1MlrEswNSPzRH0Xj9q0-487lH42RncuRXCIqd8ljf1_8v-IXMl6WtDdQDYjQE_s-OHN0BNXt0t4wTd5ikeG6NCH2SHC2wB-PchAiE5P4oHK6Vx3M0q3TEexP11Up6I9ksnpNBw256ZKPa0pX3urxLa215fDhtScA9RzA&s=OcFQKnISu4MoxtO9I1iGTNbT2srXy2EVSM1ULPFlzodZ82AfSZWqAhVoV4pzyEe4DibUPbBl1Q9u-3Hv2xKGIQhXND8pd-tpXknmRTjLinzTge15V4xQbP8Ct20wrf8KEFv3Dj8Mlhuiu10TJGskbuvrAg3DfmnDMUtoYnrT4yk8VEI44Y-aQMT4u_QYk65kQBnnSq3ZODwTV3Wq1RV7mtKCkGsqucV-1NhpF0-NI6MEdJWTiY-rhgKFbl8xl66_8OUjQezfdC6a0hLmqGGOxCEGEHAGRsA5bqzXfr2zcDwpGw9UaEoLLYdFoklQstSBVCn5HBrI1yZc5ikSHAKbNg&h=iabC062MiIDAEIu0nnddLgasL3hceI3HvtCxqsUOl7Q + response: + body: + string: '{"status":"Succeeded"}' + headers: + api-supported-versions: + - 2019-05-01-preview, 2020-11-01-preview, 2021-06-01-preview, 2021-08-01-preview, + 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, 2023-01-01-preview, 2023-06-01-preview, + 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, 2024-01-01-preview, 2024-11-01-preview, + 2025-03-01-preview, 2025-04-01, 2025-05-01-preview, 2025-06-01-preview, 2025-09-01-preview, + 2025-11-01, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, 2026-09-01-preview, + 2026-11-01 + azure-asyncoperation: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration/operationStatuses/token-a247ff8e-b576-11f1-b229-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624606387261&c=MIIHlTCCBn2gAwIBAgIRAN0yZzL8aR42UZysboj3ciowDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgRVVTMiBDQSAwMTAeFw0yNjA4MTQwMDQwMTRaFw0yNzAyMDkwNjQwMTRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzoSOkVR7MNj87TdZrq2tsL7eEWBZ1UxYUjlHs2t1x6Xn31o-6e5yM1I79Xw17HpG_ZRC01sH0DmLucuBF6EGQR50aTJ6mx22HrEe4YQhQiTieYabApNFEW7C1Z3sqhwTVaWGvV9-nw9anTx1HztS5s2jjMeJoebstq-wBIvYIOyM7hj12vYY5vdXTn9Sask3V8S3KBxdPpOFhQ5pKF6CgT-fQ9-scbzgeKeWuPXZTO0EeH02xAsj1c-lki5VGv0RewzD2beJxGO1-CxJFOfH9H3UnlZMKLg6kT-aBTn6RuYVuLJoMYYC-eHbYtahA3x5r3yutNG8gegIMlLlcdTGAQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQU7naFfTwmNksX70OjHOYQPsR55KIwHwYDVR0jBBgwFoAU_Ow-26p8H4IeBbihBvlD5wKzCrkwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9lYXN0dXMyL2NybHMvY2NtZWVhc3R1czJwa2kvY2NtZWVhc3R1czJpY2EwMS8zOS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZWVhc3R1czJwa2kuZWFzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWVlYXN0dXMyaWNhMDEvMzkvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY2FjZXJ0cy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21lZWFzdHVzMnBraS5lYXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWVhc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAJrRoJWjIzsymA0Vpio4e2hRDOWlG5PpWmWos3Gflt8XcQwRsU-vvdeWk-uT-wHYn52846N5Ue5cbvM8NV-labOA852VL2mtuHnz7bkkRfWTlP-tB-JYDS8l0yGcTENq-UNlakbleLgtfD-Qr09l853jhegiUP3vJKLXMCFF1C2maSNhwZg1MlrEswNSPzRH0Xj9q0-487lH42RncuRXCIqd8ljf1_8v-IXMl6WtDdQDYjQE_s-OHN0BNXt0t4wTd5ikeG6NCH2SHC2wB-PchAiE5P4oHK6Vx3M0q3TEexP11Up6I9ksnpNBw256ZKPa0pX3urxLa215fDhtScA9RzA&s=BYyfVl0b-cvv2dobB6IAdfiPHhXwtpBVi4qKOoz5Zjs3XBfRq1IbtH1lmdfDPFtL-6hT43ew2VkZvCDv4irSWef3ymUth2ZCzbGRqFS3k67Pux5jrJRTOAgkqcINlJX7L1amiMt5cjEV5FZdAM6j1ms2-Z1Zc2JuzmZy_W-utSIUiANbPsZ02RCDGQcGoAj78t9TlD8qmiUKwyNWgFAXn7BhleIN-bz5K7sUl2XCq83ZGgWLtfNk4ZOCEX0xOG4bwTfdDlowPaUtMegXzxMxVE3H58zhOVwKdkgk_qdobZBZly3V-Fogj-VgQQKVpLk_X3Ti3EnWBac-p1ZV2TScFQ&h=CnsMQC23z2CpepU3IKag6txIOMm1qWRu71lyST09PgM + cache-control: + - no-cache + content-length: + - '22' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:00 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/a3fa96ec-3ef5-44d2-b851-403234888a5f + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 47ECD7CF695D402A8E5E8A138BC73060 Ref B: SYD281080706036 Ref C: 2026-09-21T04:41:00Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/tokens","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:59.7573903+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:59.7573903+00:00"},"properties":{"creationDate":"2026-09-21T04:40:59.7950047+00:00","provisioningState":"Succeeded","scopeMapId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/scopeMaps/crmigration","credentials":{"passwords":[]},"status":"enabled"}}' + headers: + api-supported-versions: + - 2019-05-01-preview, 2020-11-01-preview, 2021-06-01-preview, 2021-08-01-preview, + 2021-12-01-preview, 2022-02-01-preview, 2022-12-01, 2023-01-01-preview, 2023-06-01-preview, + 2023-07-01, 2023-08-01-preview, 2023-11-01-preview, 2024-01-01-preview, 2024-11-01-preview, + 2025-03-01-preview, 2025-04-01, 2025-05-01-preview, 2025-06-01-preview, 2025-09-01-preview, + 2025-11-01, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, 2026-09-01-preview, + 2026-11-01 + cache-control: + - no-cache + content-length: + - '814' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:01 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/e8d96691-2b39-4fe7-ab82-edea8e073450 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 5A1477C2F01D40208075679BC678F22A Ref B: SYD281080712036 Ref C: 2026-09-21T04:41:01Z' + status: + code: 200 + message: OK +- request: + body: '{"properties": {"mode": "readonly", "notificationsList": ["hello-world:tag:push"], + "parent": {"syncProperties": {"tokenId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration", + "schedule": "0 0/10 * * *", "messageTtl": "P2D", "syncWindow": "PT4H", "authType": + "SyncToken"}}, "garbageCollection": {"enabled": false, "schedule": "0 0 * * + *"}, "logging": {"logLevel": "Warning", "auditLogStatus": "Disabled"}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry create + Connection: + - keep-alive + Content-Length: + - '522' + Content-Type: + - application/json + ParameterSetName: + - -n -r -g --mode --auth-type --repository --log-level --sync-schedule --sync-window + --notifications --gc-enabled + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PUT + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:02.12424+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:02.12424+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"tokenId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration","schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"SyncToken"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1192' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:01 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/62a2ba6b-a47f-4794-89e1-9236a42556d0 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 386B648B794441C181045D6D4C8E9DC8 Ref B: SYD281080707025 Ref C: 2026-09-21T04:41:01Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: AB6A15367E564FBA958003CE6B01C9AF Ref B: SYD281080705034 Ref C: 2026-09-21T04:41:02Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:02.12424+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:02.12424+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"tokenId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration","schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"SyncToken"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1192' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:02 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/c3d8ca51-f01c-48bb-b418-3bc7d1e79bbf + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A2775DE7984B4E9581DD7907880A8FE6 Ref B: SYD281080708060 Ref C: 2026-09-21T04:41:03Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry update + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:04 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 8E8D4A800B0F4AABB1DBF07BDDEEA725 Ref B: SYD281080706025 Ref C: 2026-09-21T04:41:03Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry update + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:04 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 7B3F180F50404C7588861B1618A9FC6E Ref B: SYD281080708054 Ref C: 2026-09-21T04:41:04Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry update + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:02.12424+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:02.12424+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"tokenId":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/tokens/crmigration","schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"SyncToken"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1192' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:04 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/b2f65fc2-8e7d-4f35-bb18-de78e9cc2ce1 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 1F25A72497754D61B13B8CEEE67AFD2A Ref B: SYD281080708029 Ref C: 2026-09-21T04:41:05Z' + status: + code: 200 + message: OK +- request: + body: '{"identity": {"type": "UserAssigned", "userAssignedIdentities": {"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003": + {}}}, "properties": {"syncProperties": {"authType": "ManagedIdentity"}, "garbageCollection": + {}, "logging": {}}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry update + Connection: + - keep-alive + Content-Length: + - '338' + Content-Type: + - application/json + ParameterSetName: + - -n -r -g --auth-type --identity + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: PATCH + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:05.9950386+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:05.9950386+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1352' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:05 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/b67ec326-abb5-4cfd-a2ae-f6204640afc5 + x-ms-ratelimit-remaining-subscription-global-writes: + - '11999' + x-ms-ratelimit-remaining-subscription-writes: + - '799' + x-msedge-ref: + - 'Ref A: 9D152CC29A5449A98F7BFB5DB8A2E5E0 Ref B: SYD281080705052 Ref C: 2026-09-21T04:41:05Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:06 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0497EFC463D14F2F86452DBF9FDD2DC6 Ref B: SYD281080707023 Ref C: 2026-09-21T04:41:06Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry show + Connection: + - keep-alive + ParameterSetName: + - -n -r -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:05.9950386+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:05.9950386+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1352' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:06 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/310833ec-ba6b-403a-a9ab-5456fe2eb05c + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: FC725E67DD9E452A85B865C6F73C298D Ref B: SYD281080711060 Ref C: 2026-09-21T04:41:07Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:08 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 549FDCEFE73C4DEA939953F8A55AC882 Ref B: SYD281080709023 Ref C: 2026-09-21T04:41:08Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:09 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: F3A2B892BA8D4E6F88076AAC0C973C20 Ref B: SYD281080709060 Ref C: 2026-09-21T04:41:09Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry get-settings + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --parent-protocol + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:05.9950386+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:05.9950386+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1352' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:10 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/2ec0f7b9-f1b4-4157-8a27-ef5d503c0583 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A1F504180D514629AD16DB51AA423F2A Ref B: SYD281080711034 Ref C: 2026-09-21T04:41:09Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --cleanup -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:11 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: A510166E2D774FE7B36E9DCCB7AD397D Ref B: SYD281080706031 Ref C: 2026-09-21T04:41:11Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --cleanup -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Succeeded","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1758' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:12 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0FCC3578AB8A445A91688EDDD04702FB Ref B: SYD281080707040 Ref C: 2026-09-21T04:41:11Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + ParameterSetName: + - -n -r -g --cleanup -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '{"type":"Microsoft.ContainerRegistry/registries/connectedRegistries","identity":{"type":"userAssigned","userAssignedIdentities":{"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003":{"principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration","name":"crmigration","systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:41:05.9950386+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:41:05.9950386+00:00"},"properties":{"provisioningState":"Succeeded","mode":"ReadOnly","connectionState":"Offline","activation":{"status":"Inactive"},"parent":{"syncProperties":{"schedule":"0 + 0/10 * * *","syncWindow":"PT4H","messageTtl":"P2D","gatewayEndpoint":"clireg000002.eastus.data.azurecr.io","authType":"ManagedIdentity"}},"loginServer":{"tls":{"certificate":{}}},"logging":{"logLevel":"Warning","auditLogStatus":"Disabled"},"notificationsList":["hello-world:tag:push"],"garbageCollection":{"enabled":false,"schedule":"0 + 0 * * *"}}}' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1352' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:11 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/fc52b27d-46b0-42c8-bd87-46906c400003 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 59F9408203C04104B5EE2E2EF5851D7A Ref B: SYD281080712031 Ref C: 2026-09-21T04:41:12Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr connected-registry delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -r -g --cleanup -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002/connectedRegistries/crmigration?api-version=2026-09-01-preview + response: + body: + string: '' + headers: + api-supported-versions: + - 2025-09-01-preview, 2025-12-01-preview, 2026-01-01-preview, 2026-03-01-preview, + 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:41:13 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/ed63f7ea-80e2-4988-bd01-05ef83b8feda + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: F217DF8256F240869AF724E39C8B9A3D Ref B: SYD281080710042 Ref C: 2026-09-21T04:41:13Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - identity show + Connection: + - keep-alive + ParameterSetName: + - -n -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003?api-version=2025-05-31-preview + response: + body: + string: '{"location":"eastus","tags":{},"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003","name":"cr-mi-id000003","type":"Microsoft.ManagedIdentity/userAssignedIdentities","properties":{"isolationScope":"None","assignmentRestrictions":{"providers":[]},"tenantId":"72f988bf-86f1-41af-91ab-2d7cd011db47","principalId":"eb1bd128-216b-4383-b86e-11cc2b90e7c9","clientId":"ecc4d608-39bc-45e8-a83b-10e52b43567c"}}' + headers: + cache-control: + - no-cache + content-length: + - '512' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:13 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: D7FA6E37EABE42ECB67EEF3E25B47E3F Ref B: SYD281080711060 Ref C: 2026-09-21T04:41:14Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002?api-version=2026-09-01-preview + response: + body: + string: '{"sku":{"name":"Premium","tier":"Premium"},"type":"Microsoft.ContainerRegistry/registries","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ContainerRegistry/registries/clireg000002","name":"clireg000002","location":"eastus","tags":{},"systemData":{"createdBy":"test@example.com","createdByType":"User","createdAt":"2026-09-21T04:40:39.2175714+00:00","lastModifiedBy":"test@example.com","lastModifiedByType":"User","lastModifiedAt":"2026-09-21T04:40:50.9476009+00:00"},"properties":{"loginServer":"clireg000002.azurecr.io","creationDate":"2026-09-21T04:40:39.2175714Z","provisioningState":"Deleting","adminUserEnabled":false,"networkRuleSet":{"defaultAction":"Allow","virtualNetworkRules":[],"ipRules":[]},"policies":{"quarantinePolicy":{"status":"disabled"},"trustPolicy":{"type":"Notary","status":"disabled"},"retentionPolicy":{"days":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134338+00:00","status":"disabled"},"exportPolicy":{"status":"enabled"},"azureADAuthenticationAsArmPolicy":{"status":"enabled"},"softDeletePolicy":{"retentionDays":7,"lastUpdatedTime":"2026-09-21T04:40:46.6134663+00:00","status":"disabled"}},"encryption":{"status":"disabled"},"dataEndpointEnabled":true,"regionalEndpoints":"Disabled","dataEndpointHostNames":["clireg000002.eastus.data.azurecr.io"],"regionalEndpointHostNames":[],"endpointProtocol":"IPv4","privateEndpointConnections":[],"publicNetworkAccess":"Enabled","networkRuleBypassOptions":"AzureServices","networkRuleBypassAllowedForTasks":false,"zoneRedundancy":"Disabled","anonymousPullEnabled":false,"metadataSearch":"Disabled","roleAssignmentMode":"AbacRepositoryPermissions","autoGeneratedDomainNameLabelScope":"Unsecure","writableCacheRepos":"Disabled"}}' + headers: + api-supported-versions: + - 2026-09-01-preview + cache-control: + - no-cache + content-length: + - '1757' + content-type: + - application/json; charset=utf-8 + date: + - Mon, 21 Sep 2026 04:41:14 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-ad708138-b576-11f1-8612-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624753450448&c=MIIHlTCCBn2gAwIBAgIRAN0yZzL8aR42UZysboj3ciowDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgRVVTMiBDQSAwMTAeFw0yNjA4MTQwMDQwMTRaFw0yNzAyMDkwNjQwMTRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzoSOkVR7MNj87TdZrq2tsL7eEWBZ1UxYUjlHs2t1x6Xn31o-6e5yM1I79Xw17HpG_ZRC01sH0DmLucuBF6EGQR50aTJ6mx22HrEe4YQhQiTieYabApNFEW7C1Z3sqhwTVaWGvV9-nw9anTx1HztS5s2jjMeJoebstq-wBIvYIOyM7hj12vYY5vdXTn9Sask3V8S3KBxdPpOFhQ5pKF6CgT-fQ9-scbzgeKeWuPXZTO0EeH02xAsj1c-lki5VGv0RewzD2beJxGO1-CxJFOfH9H3UnlZMKLg6kT-aBTn6RuYVuLJoMYYC-eHbYtahA3x5r3yutNG8gegIMlLlcdTGAQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQU7naFfTwmNksX70OjHOYQPsR55KIwHwYDVR0jBBgwFoAU_Ow-26p8H4IeBbihBvlD5wKzCrkwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9lYXN0dXMyL2NybHMvY2NtZWVhc3R1czJwa2kvY2NtZWVhc3R1czJpY2EwMS8zOS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZWVhc3R1czJwa2kuZWFzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWVlYXN0dXMyaWNhMDEvMzkvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY2FjZXJ0cy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21lZWFzdHVzMnBraS5lYXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWVhc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAJrRoJWjIzsymA0Vpio4e2hRDOWlG5PpWmWos3Gflt8XcQwRsU-vvdeWk-uT-wHYn52846N5Ue5cbvM8NV-labOA852VL2mtuHnz7bkkRfWTlP-tB-JYDS8l0yGcTENq-UNlakbleLgtfD-Qr09l853jhegiUP3vJKLXMCFF1C2maSNhwZg1MlrEswNSPzRH0Xj9q0-487lH42RncuRXCIqd8ljf1_8v-IXMl6WtDdQDYjQE_s-OHN0BNXt0t4wTd5ikeG6NCH2SHC2wB-PchAiE5P4oHK6Vx3M0q3TEexP11Up6I9ksnpNBw256ZKPa0pX3urxLa215fDhtScA9RzA&s=OZvJ1_qztoF-MC6TjVrQaW0VNC5Dofrxl8KLB56YTEewEUzT55hLY2S1A_hzSjsy5e9d8NlEsKRnDENOp8jQm3Aje1ByKYrNV3bt3QvPdn5-NchXJGj48H5zRTwwRfkS1A9EfDbVcPLNbIwfBDDFBhV19bCh5s5XBZ_gRPNT00hH9d9NPc7BIDdKREhGx5T-o9DWhgF-W-mVqydQeafXSuozPcSZuTUoyEPkOLotgTEWaPIKsXOxW4EbFPyxDCFuVYPIyA4jxoiB9CXiizRPX38qr3ztjUsXZHk8sKpCUP7eUqzWMR4ohy0WkNtd7a0ycvjxp4x574l4HmHCDEY_NA&h=l-ykf5qpe5v5y5SZCEFH44SBelDMNP4TcN35IUm1OtE + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/b5c7bd55-dcb8-42c5-b7c3-282ccf237f3a + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 9230E94364FF4C3DA95BCBA844BEFE4B Ref B: SYD281080706060 Ref C: 2026-09-21T04:41:14Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-ad708138-b576-11f1-8612-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624753450448&c=MIIHlTCCBn2gAwIBAgIRAN0yZzL8aR42UZysboj3ciowDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgRVVTMiBDQSAwMTAeFw0yNjA4MTQwMDQwMTRaFw0yNzAyMDkwNjQwMTRaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzoSOkVR7MNj87TdZrq2tsL7eEWBZ1UxYUjlHs2t1x6Xn31o-6e5yM1I79Xw17HpG_ZRC01sH0DmLucuBF6EGQR50aTJ6mx22HrEe4YQhQiTieYabApNFEW7C1Z3sqhwTVaWGvV9-nw9anTx1HztS5s2jjMeJoebstq-wBIvYIOyM7hj12vYY5vdXTn9Sask3V8S3KBxdPpOFhQ5pKF6CgT-fQ9-scbzgeKeWuPXZTO0EeH02xAsj1c-lki5VGv0RewzD2beJxGO1-CxJFOfH9H3UnlZMKLg6kT-aBTn6RuYVuLJoMYYC-eHbYtahA3x5r3yutNG8gegIMlLlcdTGAQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQU7naFfTwmNksX70OjHOYQPsR55KIwHwYDVR0jBBgwFoAU_Ow-26p8H4IeBbihBvlD5wKzCrkwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC9lYXN0dXMyL2NybHMvY2NtZWVhc3R1czJwa2kvY2NtZWVhc3R1czJpY2EwMS8zOS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL2Vhc3R1czIvY3Jscy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxLzM5L2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZWVhc3R1czJwa2kuZWFzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWVlYXN0dXMyaWNhMDEvMzkvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L2Vhc3R1czIvY2FjZXJ0cy9jY21lZWFzdHVzMnBraS9jY21lZWFzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vZWFzdHVzMi9jYWNlcnRzL2NjbWVlYXN0dXMycGtpL2NjbWVlYXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21lZWFzdHVzMnBraS5lYXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZWVhc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAJrRoJWjIzsymA0Vpio4e2hRDOWlG5PpWmWos3Gflt8XcQwRsU-vvdeWk-uT-wHYn52846N5Ue5cbvM8NV-labOA852VL2mtuHnz7bkkRfWTlP-tB-JYDS8l0yGcTENq-UNlakbleLgtfD-Qr09l853jhegiUP3vJKLXMCFF1C2maSNhwZg1MlrEswNSPzRH0Xj9q0-487lH42RncuRXCIqd8ljf1_8v-IXMl6WtDdQDYjQE_s-OHN0BNXt0t4wTd5ikeG6NCH2SHC2wB-PchAiE5P4oHK6Vx3M0q3TEexP11Up6I9ksnpNBw256ZKPa0pX3urxLa215fDhtScA9RzA&s=OZvJ1_qztoF-MC6TjVrQaW0VNC5Dofrxl8KLB56YTEewEUzT55hLY2S1A_hzSjsy5e9d8NlEsKRnDENOp8jQm3Aje1ByKYrNV3bt3QvPdn5-NchXJGj48H5zRTwwRfkS1A9EfDbVcPLNbIwfBDDFBhV19bCh5s5XBZ_gRPNT00hH9d9NPc7BIDdKREhGx5T-o9DWhgF-W-mVqydQeafXSuozPcSZuTUoyEPkOLotgTEWaPIKsXOxW4EbFPyxDCFuVYPIyA4jxoiB9CXiizRPX38qr3ztjUsXZHk8sKpCUP7eUqzWMR4ohy0WkNtd7a0ycvjxp4x574l4HmHCDEY_NA&h=l-ykf5qpe5v5y5SZCEFH44SBelDMNP4TcN35IUm1OtE + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:41:15 GMT + expires: + - '-1' + location: + - https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-ad708138-b576-11f1-8612-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624766329565&c=MIIHlTCCBn2gAwIBAgIRAPRMjwgFgYEmfefMzTACKKQwDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgV1VTMiBDQSAwMTAeFw0yNjA4MTQwMDUxMjNaFw0yNzAyMDkwNjUxMjNaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwO_WpR6Xr2lz5oFVtaRK8FiZGg7b-PWeL-Dogy0Cr-qJhUgwo0Hqhe5nZmG2OL7c3CV71c0njXVt4nqBxWLM-CYPCPRB5c_xQ3lWFYnJFuP5lpJcW4uZXUHp8eZTQtInUyLcK0jXbihFpBBxuDm-xtr12Nkoqlx6yfZthAf7X6nB-Nuq26aPqupUCz6hZNjOtE7BUQY499BrTsag1LYCTzXxrkHU9figVwTEB45ZBG40HxC45VUtUdNGtwILcvy145pR4VtdCfskQErR2tLvJYujyFBPwEaJbCjjg2I1v7yWN6nrl1enYFSNx4MBskHhL6EQxWUAfo6IVyV85F9MoQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQUUdq1KVdmsEox8BScI1WzBgBA700wHwYDVR0jBBgwFoAUrONy-gOyc549lcjvh1uu3Ruh7WgwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkxL2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC93ZXN0dXMyL2NybHMvY2NtZXdlc3R1czJwa2kvY2NtZXdlc3R1czJpY2EwMS85MS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkxL2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZXdlc3R1czJwa2kud2VzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWV3ZXN0dXMyaWNhMDEvOTEvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY2FjZXJ0cy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21ld2VzdHVzMnBraS53ZXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZXdlc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAKcH3XHRFmCqmjLmxABqawQYyIEqlIbq0Ba_dNN6BRkjWSrxWZutW-VgnQV_hVg5p2AtqFKVXKbf9oTaSl3Skd60_jTB_UiVMwJQXe1Lqe_KvIxdSTigB2URtOmQbyJmVQ78A-PH__nQ3si9J4f4_0C8pfMN42X8eIofyFEcaNxOMslJaba_Ber-fVFYnl3Ble7fQL67IV004LBcHkBvnYh2Xdi1sJpCbVSWb8-URtUiV5cbz1KgImEEzn7YTGQksXJCsSxcrGKLboCmWsn8zaUbhd1gA8M4giY8jHxeVXMvNNISFWZYx4OJ5f-B9TGnvWZEGCnf-LAn1ed9ImLRvcA&s=m83btO1cflWs466cpcBtZBhEcGSyzU_owxfxLYhhYvklETNpSGWEhStNeV7atFzI6ON9VlRWLgGBJ_7_saPMbMMT3KegDOUsWzxpfM59VkOTMyuUnKH2D51BO4coXcJhwhm2aFtTr2knYxFfr3Mq0SFlXz17JzWCveox65pMmzF7SIlKcWCBik6lpNxyIQofty8KrsnCNKETbhFlofBWHO2tF3Dm91fNG5HNfX7xTVvf93ItyLjt_ejPjg5ZQo9Xvn_kD7NP1AqGUWmKQOvmrX5gY3ppZhr3z5dfssyefDEdGtGnnBlTGhpXHY3uk9k5ozIWrI1SFARwh7-xu7u3lQ&h=Tg5io5B_LogWcttCln3LPeEzNTKhozG3e56FLY2rZmo + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/c79fa35e-56c2-4c3e-b986-548a14c8de8f + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 91BBEE9EE76A4E66AC0F8304367F4ABD Ref B: SYD281080709034 Ref C: 2026-09-21T04:41:15Z' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - acr delete + Connection: + - keep-alive + ParameterSetName: + - -n -g -y + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ContainerRegistry/locations/eastus/operationResults/delete-clireg000002-ad708138-b576-11f1-8612-3cefa50a58cc?api-version=2026-09-01-preview&t=639255624766329565&c=MIIHlTCCBn2gAwIBAgIRAPRMjwgFgYEmfefMzTACKKQwDQYJKoZIhvcNAQELBQAwNjE0MDIGA1UEAxMrQ0NNRSBHMSBUTFMgUlNBIDIwNDggU0hBMjU2IDIwNDkgV1VTMiBDQSAwMTAeFw0yNjA4MTQwMDUxMjNaFw0yNzAyMDkwNjUxMjNaMEAxPjA8BgNVBAMTNWFzeW5jb3BlcmF0aW9uc2lnbmluZ2NlcnRpZmljYXRlLm1hbmFnZW1lbnQuYXp1cmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwO_WpR6Xr2lz5oFVtaRK8FiZGg7b-PWeL-Dogy0Cr-qJhUgwo0Hqhe5nZmG2OL7c3CV71c0njXVt4nqBxWLM-CYPCPRB5c_xQ3lWFYnJFuP5lpJcW4uZXUHp8eZTQtInUyLcK0jXbihFpBBxuDm-xtr12Nkoqlx6yfZthAf7X6nB-Nuq26aPqupUCz6hZNjOtE7BUQY499BrTsag1LYCTzXxrkHU9figVwTEB45ZBG40HxC45VUtUdNGtwILcvy145pR4VtdCfskQErR2tLvJYujyFBPwEaJbCjjg2I1v7yWN6nrl1enYFSNx4MBskHhL6EQxWUAfo6IVyV85F9MoQIDAQABo4IEkjCCBI4wgZ0GA1UdIASBlTCBkjAMBgorBgEEAYI3ewEBMGYGCisGAQQBgjd7AgIwWDBWBggrBgEFBQcCAjBKHkgAMwAzAGUAMAAxADkAMgAxAC0ANABkADYANAAtADQAZgA4AGMALQBhADAANQA1AC0ANQBiAGQAYQBmAGYAZAA1AGUAMwAzAGQwDAYKKwYBBAGCN3sDAjAMBgorBgEEAYI3ewQCMAwGA1UdEwEB_wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB_wQEAwIFoDAdBgNVHQ4EFgQUUdq1KVdmsEox8BScI1WzBgBA700wHwYDVR0jBBgwFoAUrONy-gOyc549lcjvh1uu3Ruh7WgwggGyBgNVHR8EggGpMIIBpTBpoGegZYZjaHR0cDovL3ByaW1hcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkxL2N1cnJlbnQuY3JsMGugaaBnhmVodHRwOi8vc2Vjb25kYXJ5LWNkbi5wa2kuY29yZS53aW5kb3dzLm5ldC93ZXN0dXMyL2NybHMvY2NtZXdlc3R1czJwa2kvY2NtZXdlc3R1czJpY2EwMS85MS9jdXJyZW50LmNybDBaoFigVoZUaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3dlc3R1czIvY3Jscy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxLzkxL2N1cnJlbnQuY3JsMG-gbaBrhmlodHRwOi8vY2NtZXdlc3R1czJwa2kud2VzdHVzMi5wa2kuY29yZS53aW5kb3dzLm5ldC9jZXJ0aWZpY2F0ZUF1dGhvcml0aWVzL2NjbWV3ZXN0dXMyaWNhMDEvOTEvY3VycmVudC5jcmwwggG3BggrBgEFBQcBAQSCAakwggGlMGwGCCsGAQUFBzAChmBodHRwOi8vcHJpbWFyeS1jZG4ucGtpLmNvcmUud2luZG93cy5uZXQvd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwbgYIKwYBBQUHMAKGYmh0dHA6Ly9zZWNvbmRhcnktY2RuLnBraS5jb3JlLndpbmRvd3MubmV0L3dlc3R1czIvY2FjZXJ0cy9jY21ld2VzdHVzMnBraS9jY21ld2VzdHVzMmljYTAxL2NlcnQuY2VyMF0GCCsGAQUFBzAChlFodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vd2VzdHVzMi9jYWNlcnRzL2NjbWV3ZXN0dXMycGtpL2NjbWV3ZXN0dXMyaWNhMDEvY2VydC5jZXIwZgYIKwYBBQUHMAKGWmh0dHA6Ly9jY21ld2VzdHVzMnBraS53ZXN0dXMyLnBraS5jb3JlLndpbmRvd3MubmV0L2NlcnRpZmljYXRlQXV0aG9yaXRpZXMvY2NtZXdlc3R1czJpY2EwMTANBgkqhkiG9w0BAQsFAAOCAQEAKcH3XHRFmCqmjLmxABqawQYyIEqlIbq0Ba_dNN6BRkjWSrxWZutW-VgnQV_hVg5p2AtqFKVXKbf9oTaSl3Skd60_jTB_UiVMwJQXe1Lqe_KvIxdSTigB2URtOmQbyJmVQ78A-PH__nQ3si9J4f4_0C8pfMN42X8eIofyFEcaNxOMslJaba_Ber-fVFYnl3Ble7fQL67IV004LBcHkBvnYh2Xdi1sJpCbVSWb8-URtUiV5cbz1KgImEEzn7YTGQksXJCsSxcrGKLboCmWsn8zaUbhd1gA8M4giY8jHxeVXMvNNISFWZYx4OJ5f-B9TGnvWZEGCnf-LAn1ed9ImLRvcA&s=m83btO1cflWs466cpcBtZBhEcGSyzU_owxfxLYhhYvklETNpSGWEhStNeV7atFzI6ON9VlRWLgGBJ_7_saPMbMMT3KegDOUsWzxpfM59VkOTMyuUnKH2D51BO4coXcJhwhm2aFtTr2knYxFfr3Mq0SFlXz17JzWCveox65pMmzF7SIlKcWCBik6lpNxyIQofty8KrsnCNKETbhFlofBWHO2tF3Dm91fNG5HNfX7xTVvf93ItyLjt_ejPjg5ZQo9Xvn_kD7NP1AqGUWmKQOvmrX5gY3ppZhr3z5dfssyefDEdGtGnnBlTGhpXHY3uk9k5ozIWrI1SFARwh7-xu7u3lQ&h=Tg5io5B_LogWcttCln3LPeEzNTKhozG3e56FLY2rZmo + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:41:27 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/australiaeast/9095003b-b4f2-408a-b0ac-43e6ea44ff64 + x-ms-ratelimit-remaining-subscription-global-reads: + - '16499' + x-msedge-ref: + - 'Ref A: 0C1B3DAAF40D4D1AA99A84A8487B2CA7 Ref B: SYD281080707025 Ref C: 2026-09-21T04:41:27Z' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - identity delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - -n -g + User-Agent: + - AZURECLI/2.90.0 azsdk-python-core/1.39.0 Python/3.13.15 (Windows-11-10.0.26100-SP0) + method: DELETE + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cr-mi-id000003?api-version=2025-05-31-preview + response: + body: + string: '' + headers: + cache-control: + - no-cache + content-length: + - '0' + date: + - Mon, 21 Sep 2026 04:41:31 GMT + expires: + - '-1' + pragma: + - no-cache + strict-transport-security: + - max-age=31536000; includeSubDomains + x-cache: + - CONFIG_NOCACHE + x-content-type-options: + - nosniff + x-ms-operation-identifier: + - tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47,objectId=4b5b0cef-cf82-4cf5-9ab1-ff84c9f11f35/eastus/b034e8eb-29ce-434a-aa88-4759b8a04a0b + x-ms-ratelimit-remaining-subscription-deletes: + - '799' + x-ms-ratelimit-remaining-subscription-global-deletes: + - '11999' + x-msedge-ref: + - 'Ref A: 3BA520F5C1C848E4B37DD41A821C97DA Ref B: SYD281080712036 Ref C: 2026-09-21T04:41:28Z' + status: + code: 200 + message: OK +version: 1 diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connected_registry_mi_unit.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connected_registry_mi_unit.py new file mode 100644 index 00000000000..11ec19c5b7f --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connected_registry_mi_unit.py @@ -0,0 +1,812 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +"""Unit tests for managed-identity connected registry creation, deletion, permissions, update, and settings.""" + +import unittest +from unittest import mock + +from azure.core.exceptions import HttpResponseError +from azure.cli.core.azclierror import ArgumentUsageError +from knack.util import CLIError + +from azure.mgmt.containerregistry import models +from azure.mgmt.containerregistry.models import ( + ManagedServiceIdentity, + ManagedServiceIdentityType, + UserAssignedIdentity, +) + +from azure.cli.command_modules.acr._constants import ConnectedRegistryAuthType + +from azure.cli.command_modules.acr.connected_registry import ( + _build_user_assigned_identity, + _get_current_auth_type, + acr_connected_registry_create, + acr_connected_registry_delete, + acr_connected_registry_get_settings, + acr_connected_registry_permissions_show, + acr_connected_registry_permissions_update, + acr_connected_registry_update, + AUTH_TYPE_MANAGED_IDENTITY, + AUTH_TYPE_SYNC_TOKEN, + MSI_TYPE_USER_ASSIGNED, +) + + +TEST_SUB = '00000000-0000-0000-0000-000000000001' +TEST_RG = 'rg' +TEST_REGISTRY = 'testreg' +TEST_CR = 'testcr123' +TEST_MSI_ID = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ManagedIdentity/' + 'userAssignedIdentities/msi1'.format(TEST_SUB, TEST_RG) +) +TEST_MSI_ID2 = TEST_MSI_ID.replace('msi1', 'msi2') + + +def _make_cmd(): + cmd = mock.MagicMock() + cmd.cli_ctx = mock.MagicMock() + return cmd + + +def _fake_cr(auth_type=None, has_identity=False, connection_state=None, + token_id=None, gateway_endpoint='parent.example.com', client_id='cid-1'): + """Build a fake connected-registry return object shaped like the SDK model.""" + cr = mock.MagicMock() + cr.name = TEST_CR + cr.mode = 'ReadOnly' + cr.connection_state = connection_state + cr.client_token_ids = None + cr.notifications_list = None + cr.parent = mock.MagicMock() + cr.parent.id = None + cr.parent.sync_properties = mock.MagicMock() + # Real MI-configured connected registries always have authType=ManagedIdentity set alongside + # the identity. Preserve that invariant when callers don't override auth_type explicitly. + if auth_type is None and has_identity: + auth_type = AUTH_TYPE_MANAGED_IDENTITY + cr.parent.sync_properties.auth_type = auth_type + cr.parent.sync_properties.token_id = token_id + cr.parent.sync_properties.gateway_endpoint = gateway_endpoint + if has_identity: + cr.identity = mock.MagicMock() + cr.identity.type = MSI_TYPE_USER_ASSIGNED + msi = mock.MagicMock() + msi.client_id = client_id + cr.identity.user_assigned_identities = {TEST_MSI_ID: msi} + else: + cr.identity = None + return cr + + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + + +class TestConstantsSourcedFromEnum(unittest.TestCase): + """The module constants must match the ConnectedRegistryAuthType enum values verbatim.""" + + def test_auth_type_constants(self): + self.assertEqual(AUTH_TYPE_SYNC_TOKEN, ConnectedRegistryAuthType.SYNC_TOKEN.value) + self.assertEqual(AUTH_TYPE_MANAGED_IDENTITY, ConnectedRegistryAuthType.MANAGED_IDENTITY.value) + + def test_msi_type_constant(self): + self.assertEqual(MSI_TYPE_USER_ASSIGNED, ManagedServiceIdentityType.USER_ASSIGNED.value) + + +# --------------------------------------------------------------------------- +# Helper: _get_current_auth_type +# --------------------------------------------------------------------------- + + +class TestGetCurrentAuthType(unittest.TestCase): + + def test_managed_identity_auth_type(self): + cr = _fake_cr(auth_type=AUTH_TYPE_MANAGED_IDENTITY, has_identity=True) + self.assertEqual(_get_current_auth_type(cr), AUTH_TYPE_MANAGED_IDENTITY) + + def test_sync_token_auth_type_no_identity(self): + cr = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN, has_identity=False) + self.assertEqual(_get_current_auth_type(cr), AUTH_TYPE_SYNC_TOKEN) + + def test_missing_auth_type_defaults_to_sync_token(self): + cr = _fake_cr(auth_type=None, has_identity=False) + self.assertEqual(_get_current_auth_type(cr), AUTH_TYPE_SYNC_TOKEN) + + def test_enum_valued_auth_type_is_coerced_to_string(self): + cr = _fake_cr(auth_type=ConnectedRegistryAuthType.MANAGED_IDENTITY, has_identity=False) + result = _get_current_auth_type(cr) + self.assertEqual(result, AUTH_TYPE_MANAGED_IDENTITY) + self.assertIsInstance(result, str) + self.assertNotIn('ConnectedRegistryAuthType.', result) + + +# --------------------------------------------------------------------------- +# Helper: _build_user_assigned_identity +# --------------------------------------------------------------------------- + + +class TestBuildUserAssignedIdentity(unittest.TestCase): + + def test_shape(self): + cmd = _make_cmd() + cmd.get_models.return_value = (ManagedServiceIdentity, UserAssignedIdentity) + identity = _build_user_assigned_identity(cmd, TEST_MSI_ID) + self.assertIsInstance(identity, ManagedServiceIdentity) + self.assertEqual(identity.type, MSI_TYPE_USER_ASSIGNED) + self.assertIn(TEST_MSI_ID, identity.user_assigned_identities) + self.assertIsInstance( + identity.user_assigned_identities[TEST_MSI_ID], UserAssignedIdentity) + + +# --------------------------------------------------------------------------- +# create: client-side argument validation +# --------------------------------------------------------------------------- + + +class TestConnectedRegistryCreateValidation(unittest.TestCase): + + def _create(self, **overrides): + kwargs = dict( + cmd=_make_cmd(), + client=mock.MagicMock(), + registry_name=TEST_REGISTRY, + connected_registry_name=TEST_CR, + mode='ReadOnly', + ) + kwargs.update(overrides) + return acr_connected_registry_create(**kwargs) + + def test_mi_requires_identity(self): + with self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY) + + def test_mi_rejects_sync_token(self): + with self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, + identity=TEST_MSI_ID, sync_token_name='tok') + + def test_mi_rejects_repository(self): + with self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, + identity=TEST_MSI_ID, repositories=['r1']) + + def test_sync_token_rejects_identity(self): + with self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_SYNC_TOKEN, identity=TEST_MSI_ID, + sync_token_name='tok') + + def test_sync_token_requires_exactly_one_of_token_or_repos(self): + with self.assertRaises(CLIError): + # neither + self._create(auth_type=AUTH_TYPE_SYNC_TOKEN) + with self.assertRaises(CLIError): + # both + self._create(auth_type=AUTH_TYPE_SYNC_TOKEN, + sync_token_name='tok', repositories=['r1']) + + def test_short_name_rejected(self): + with self.assertRaises(Exception): # InvalidArgumentValueError + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, + identity=TEST_MSI_ID, + connected_registry_name='abc') # < 5 chars + + def test_mi_rejects_blank_identity(self): + for identity in ('', ' ', '\t'): + with self.subTest(identity=identity), self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=identity) + + def test_mi_rejects_explicit_empty_token_or_repositories(self): + for options in ({'sync_token_name': ''}, {'repositories': []}, {'repositories': ['']}): + with self.subTest(options=options), self.assertRaises(ArgumentUsageError): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID, **options) + + def test_identity_requires_explicit_managed_identity_auth(self): + for auth_type in (None, AUTH_TYPE_SYNC_TOKEN): + for identity in ('', TEST_MSI_ID): + with self.subTest(auth_type=auth_type, identity=identity), \ + self.assertRaises(ArgumentUsageError): + self._create(auth_type=auth_type, identity=identity, sync_token_name='tok') + + def test_mi_rejects_parent_before_registry_lookup(self): + with mock.patch(UPDATE_MODULE + '.get_registry_by_name') as get_registry, \ + mock.patch(UPDATE_MODULE + '.get_subscription_id') as get_subscription: + for parent_name in ('parentcr', ''): + with self.subTest(parent_name=parent_name), self.assertRaisesRegex(ArgumentUsageError, '--parent'): + self._create(auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID, + parent_name=parent_name) + get_registry.assert_not_called() + get_subscription.assert_not_called() + + +class TestConnectedRegistryCreatePayload(unittest.TestCase): + + def test_root_auth_payload_and_token_paths(self): + for auth_type, options in ( + (AUTH_TYPE_MANAGED_IDENTITY, {'identity': TEST_MSI_ID}), + (None, {'sync_token_name': 'sync-token'}), + (AUTH_TYPE_SYNC_TOKEN, {'repositories': ['r1']})): + with self.subTest(auth_type=auth_type): + cmd = _make_cmd() + cmd.get_models.side_effect = lambda *names: tuple(getattr(models, name) for name in names) + client = mock.MagicMock() + registry = mock.MagicMock(data_endpoint_enabled=True) + token_id = '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/registries/{}/tokens/sync-token'.format( + TEST_SUB, TEST_RG, TEST_REGISTRY) + client_token_id = token_id.replace('/tokens/sync-token', '/tokens/client-token') + with mock.patch(UPDATE_MODULE + '.get_subscription_id', return_value=TEST_SUB), \ + mock.patch(UPDATE_MODULE + '.get_registry_by_name', return_value=(registry, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '._create_sync_token', return_value=token_id) as create_token, \ + mock.patch(UPDATE_MODULE + '.cf_acr_tokens') as tokens, \ + mock.patch(UPDATE_MODULE + '.cf_acr_scope_maps') as scope_maps, \ + mock.patch(UPDATE_MODULE + '._update_ancestor_permissions') as update_permissions: + result = acr_connected_registry_create( + cmd, client, TEST_REGISTRY, TEST_CR, mode='ReadOnly', auth_type=auth_type, + client_token_list=['client-token'], sync_schedule='0 12 * * *', sync_window='PT4H', + sync_message_ttl='P2D', log_level='Information', sync_audit_logs_enabled=True, + garbage_collection_enabled=True, garbage_collection_schedule='0 0 * * *', + notifications=['hello:latest', 'hello:latest'], **options) + self.assertIs(result, client.begin_create.return_value) + client.begin_create.assert_called_once() + call = client.begin_create.call_args.kwargs + self.assertEqual(call['resource_group_name'], TEST_RG) + self.assertEqual(call['registry_name'], TEST_REGISTRY) + self.assertEqual(call['connected_registry_name'], TEST_CR) + parameters = call['connected_registry_create_parameters'] + self.assertIsInstance(parameters, models.ConnectedRegistry) + expected_sync = { + 'authType': auth_type or AUTH_TYPE_SYNC_TOKEN, + 'schedule': '0 12 * * *', + 'messageTtl': 'P2D', + 'syncWindow': 'PT4H', + } + if auth_type == AUTH_TYPE_MANAGED_IDENTITY: + self.assertEqual(parameters.identity.as_dict(), { + 'type': 'UserAssigned', 'userAssignedIdentities': {TEST_MSI_ID: {}}}) + self.assertIsNone(parameters.parent.sync_properties.token_id) + create_token.assert_not_called() + else: + self.assertIsNone(parameters.identity) + expected_sync['tokenId'] = token_id + if 'repositories' in options: + create_token.assert_called_once_with( + cmd, TEST_RG, TEST_REGISTRY, TEST_CR, ['r1'], 'readonly') + else: + create_token.assert_not_called() + self.assertIsNone(parameters.parent.id) + self.assertEqual(parameters.parent.sync_properties.as_dict(), expected_sync) + self.assertEqual(parameters.mode, 'readonly') + self.assertEqual(parameters.client_token_ids, [client_token_id]) + self.assertEqual(parameters.logging.as_dict(), { + 'logLevel': 'Information', 'auditLogStatus': 'Enabled'}) + self.assertEqual(parameters.garbage_collection.as_dict(), { + 'enabled': True, 'schedule': '0 0 * * *'}) + self.assertEqual(parameters.notifications_list, ['hello:latest']) + client.get.assert_not_called() + client.list.assert_not_called() + tokens.assert_not_called() + scope_maps.assert_not_called() + update_permissions.assert_not_called() + + +UPDATE_MODULE = 'azure.cli.command_modules.acr.connected_registry' + + +class TestConnectedRegistryDelete(unittest.TestCase): + + def test_mi_delete_skips_token_cleanup(self): + token_id = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/' + 'registries/{}/tokens/old-sync'.format(TEST_SUB, TEST_RG, TEST_REGISTRY)) + for cleanup in (False, True): + for auth_type in (AUTH_TYPE_MANAGED_IDENTITY, models.AuthType.MANAGED_IDENTITY): + for previous_token in (None, token_id): + with self.subTest(cleanup=cleanup, auth_type=auth_type, token_id=previous_token): + cr = _fake_cr(auth_type=auth_type, has_identity=True, token_id=previous_token) + cmd = _make_cmd() + client = mock.MagicMock() + client.get.return_value = cr + client.begin_delete.return_value.result.return_value = mock.sentinel.deleted + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.user_confirmation') as confirm, \ + mock.patch(UPDATE_MODULE + '.get_token_from_id') as token_lookup, \ + mock.patch(UPDATE_MODULE + '.get_scope_map_from_id') as scope_lookup, \ + mock.patch(UPDATE_MODULE + '.cf_acr_tokens') as tokens, \ + mock.patch(UPDATE_MODULE + '.cf_acr_scope_maps') as scope_maps, \ + mock.patch('azure.cli.command_modules.acr.token.acr_token_delete') as delete_token, \ + mock.patch('azure.cli.command_modules.acr.scope_map.acr_scope_map_delete') as delete_scope, \ + mock.patch(UPDATE_MODULE + '._get_family_tree') as family_tree, \ + mock.patch(UPDATE_MODULE + '._update_ancestor_permissions') as update_permissions, \ + mock.patch(UPDATE_MODULE + '.logger.warning') as warning: + result = acr_connected_registry_delete( + cmd, client, TEST_CR, TEST_REGISTRY, cleanup=cleanup, resource_group_name=TEST_RG) + self.assertIs(result, mock.sentinel.deleted) + client.get.assert_called_once_with(TEST_RG, TEST_REGISTRY, TEST_CR) + client.begin_delete.assert_called_once_with(TEST_RG, TEST_REGISTRY, TEST_CR) + client.begin_delete.return_value.result.assert_called_once_with() + self.assertEqual(client.mock_calls, [ + mock.call.get(TEST_RG, TEST_REGISTRY, TEST_CR), + mock.call.begin_delete(TEST_RG, TEST_REGISTRY, TEST_CR), + mock.call.begin_delete().result(), + ]) + confirm.assert_called_once_with( + "Are you sure you want to delete the connected registry '{}' in '{}'?".format( + TEST_CR, TEST_REGISTRY), False) + token_lookup.assert_not_called() + scope_lookup.assert_not_called() + tokens.assert_not_called() + scope_maps.assert_not_called() + delete_token.assert_not_called() + delete_scope.assert_not_called() + family_tree.assert_not_called() + update_permissions.assert_not_called() + if cleanup: + warning.assert_called_once_with( + "'--cleanup' has no effect for connected registry '%s' using " + "ManagedIdentity authentication. The managed identity and role assignments " + "are retained.", TEST_CR) + else: + warning.assert_not_called() + + def test_mi_failed_delete_does_not_report_cleanup_success(self): + cr = _fake_cr(has_identity=True) + client = mock.MagicMock() + client.get.return_value = cr + error = HttpResponseError(message='Connected registry deletion failed.') + client.begin_delete.return_value.result.side_effect = error + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.user_confirmation'), \ + mock.patch(UPDATE_MODULE + '.get_token_from_id') as token_lookup, \ + mock.patch(UPDATE_MODULE + '.logger.warning') as warning: + with self.assertRaises(HttpResponseError) as caught: + acr_connected_registry_delete( + _make_cmd(), client, TEST_CR, TEST_REGISTRY, cleanup=True, yes=True, resource_group_name=TEST_RG) + self.assertIs(caught.exception, error) + token_lookup.assert_not_called() + warning.assert_not_called() + + def test_sync_token_delete_preserves_cleanup_and_warning(self): + token_id = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/' + 'registries/{}/tokens/sync'.format(TEST_SUB, TEST_RG, TEST_REGISTRY)) + for cleanup in (False, True): + for auth_type in (AUTH_TYPE_SYNC_TOKEN, models.AuthType.SYNC_TOKEN, None): + with self.subTest(cleanup=cleanup, auth_type=auth_type): + cr = _fake_cr(auth_type=auth_type, token_id=token_id) + cr.parent.id = '/connectedRegistries/parent' + cmd = _make_cmd() + client = mock.MagicMock() + client.get.return_value = cr + client.begin_delete.return_value.result.return_value = mock.sentinel.deleted + client.list.return_value = [mock.sentinel.parent] + token = mock.MagicMock() + token.name = 'sync' + token.scope_map_id = token_id.replace('/tokens/sync', '/scopeMaps/sync-scope') + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.user_confirmation') as confirm, \ + mock.patch(UPDATE_MODULE + '.get_token_from_id', return_value=token) as token_lookup, \ + mock.patch(UPDATE_MODULE + '.cf_acr_tokens') as tokens, \ + mock.patch(UPDATE_MODULE + '.cf_acr_scope_maps') as scope_maps, \ + mock.patch('azure.cli.command_modules.acr.token.acr_token_delete') as delete_token, \ + mock.patch('azure.cli.command_modules.acr.scope_map.acr_scope_map_delete') as delete_scope, \ + mock.patch(UPDATE_MODULE + '._get_family_tree', + return_value=(mock.sentinel.family_tree, None)) as family_tree, \ + mock.patch(UPDATE_MODULE + '._update_ancestor_permissions') as update_permissions, \ + mock.patch(UPDATE_MODULE + '.logger.warning') as warning: + result = acr_connected_registry_delete( + cmd, client, TEST_CR, TEST_REGISTRY, cleanup=cleanup, yes=True, resource_group_name=TEST_RG) + self.assertIs(result, mock.sentinel.deleted) + client.get.assert_called_once_with(TEST_RG, TEST_REGISTRY, TEST_CR) + client.begin_delete.assert_called_once_with(TEST_RG, TEST_REGISTRY, TEST_CR) + client.begin_delete.return_value.result.assert_called_once_with() + confirm.assert_called_once_with( + "Are you sure you want to delete the connected registry '{}' in '{}'{}?".format( + TEST_CR, TEST_REGISTRY, '' if cleanup else ' without cleanup flag enabled'), True) + token_lookup.assert_called_once_with(cmd, token_id) + if cleanup: + tokens.assert_called_once_with(cmd.cli_ctx) + scope_maps.assert_called_once_with(cmd.cli_ctx) + delete_token.assert_called_once_with( + cmd, tokens.return_value, TEST_REGISTRY, 'sync', True, TEST_RG) + delete_token.return_value.result.assert_called_once_with() + delete_scope.assert_called_once_with( + cmd, scope_maps.return_value, TEST_REGISTRY, 'sync-scope', True, TEST_RG) + delete_scope.return_value.result.assert_called_once_with() + client.list.assert_called_once_with(TEST_RG, TEST_REGISTRY) + family_tree.assert_called_once_with([mock.sentinel.parent], None) + update_permissions.assert_called_once_with( + cmd, mock.sentinel.family_tree, TEST_RG, TEST_REGISTRY, + cr.parent.id, TEST_CR, remove_access=True) + warning.assert_not_called() + else: + tokens.assert_not_called() + scope_maps.assert_not_called() + delete_token.assert_not_called() + delete_scope.assert_not_called() + client.list.assert_not_called() + family_tree.assert_not_called() + update_permissions.assert_not_called() + warning.assert_called_once_with( + "Connected registry successfully deleted. Please cleanup your sync tokens and scope maps. " + "Run the following commands for cleanup: \n\t" + "az acr token delete -n sync -r {registry} --yes\n\t" + "az acr scope-map delete -n sync-scope -r {registry} --yes\n" + "Run the following command on all ascendency to remove the deleted registry gateway access: " + "\n\taz acr scope-map update -n -r {registry} --remove-gateway " + "{connected_registry} config/read config/write message/read message/write".format( + registry=TEST_REGISTRY, connected_registry=TEST_CR)) + + +# --------------------------------------------------------------------------- +# permissions show / update: blocked on MI +# --------------------------------------------------------------------------- + + +class TestConnectedRegistryPermissionsMI(unittest.TestCase): + + def test_permissions_show_blocked_on_mi(self): + cr = _fake_cr(has_identity=True) + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.acr_connected_registry_show', + return_value=cr): + with self.assertRaises(ArgumentUsageError): + acr_connected_registry_permissions_show( + cmd=_make_cmd(), client=mock.MagicMock(), + connected_registry_name=TEST_CR, registry_name=TEST_REGISTRY, + resource_group_name=TEST_RG) + + def test_permissions_update_blocked_on_mi(self): + cr = _fake_cr(has_identity=True) + client = mock.MagicMock() + client.list.return_value = [cr] + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)): + with self.assertRaises(ArgumentUsageError): + acr_connected_registry_permissions_update( + cmd=_make_cmd(), client=client, + connected_registry_name=TEST_CR, registry_name=TEST_REGISTRY, + add_repos=['r1'], resource_group_name=TEST_RG) + + +# --------------------------------------------------------------------------- +# update: input validation and PATCH shape +# --------------------------------------------------------------------------- + + +class TestConnectedRegistryUpdateMigration(unittest.TestCase): + + def _patch_common(self): + p_validate = mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)) + p_subid = mock.patch(UPDATE_MODULE + '.get_subscription_id', + return_value=TEST_SUB) + return p_validate, p_subid + + def _run_update(self, current, **overrides): + client = mock.MagicMock() + cmd = _make_cmd() + cmd.get_models.side_effect = lambda *names: tuple(getattr(models, name) for name in names) + kwargs = dict( + cmd=cmd, + client=client, + registry_name=TEST_REGISTRY, + connected_registry_name=TEST_CR, + resource_group_name=TEST_RG, + ) + kwargs.update(overrides) + p_validate, p_subid = self._patch_common() + with p_validate, p_subid, \ + mock.patch(UPDATE_MODULE + '.acr_connected_registry_show', return_value=current): + acr_connected_registry_update(**kwargs) + return client + + # ---- error paths ------------------------------------------------------ + + def test_identity_without_auth_type_errors(self): + cur = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN) + for identity in (TEST_MSI_ID, '', ' ', '\t', '\n'): + with self.subTest(identity=identity): + client = mock.MagicMock() + with self.assertRaisesRegex(ArgumentUsageError, '--auth-type is required'): + self._run_update(cur, client=client, identity=identity) + client.begin_update.assert_not_called() + + def test_migration_rejects_existing_managed_identity(self): + for identity in (TEST_MSI_ID, TEST_MSI_ID2): + with self.subTest(identity=identity): + cur = _fake_cr(has_identity=True, connection_state='Offline') + client = mock.MagicMock() + with self.assertRaisesRegex(ArgumentUsageError, "already using 'ManagedIdentity'"): + self._run_update(cur, client=client, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=identity) + client.begin_update.assert_not_called() + + def test_migration_requires_offline_connection_state(self): + for state in ('Online', models.ConnectionState.ONLINE, None): + with self.subTest(state=state): + cur = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN, connection_state=state) + client = mock.MagicMock() + with self.assertRaisesRegex(ArgumentUsageError, "must be in 'Offline' state"): + self._run_update(cur, client=client, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID) + client.begin_update.assert_not_called() + + def test_migration_service_errors_propagate_after_local_validation(self): + cur = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN, connection_state='Offline') + client = mock.MagicMock() + error = HttpResponseError(message='The requested migration is not allowed.') + client.begin_update.side_effect = error + with self.assertRaises(HttpResponseError) as caught: + self._run_update(cur, client=client, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID) + self.assertIs(caught.exception, error) + client.begin_update.assert_called_once() + + def test_migrate_to_mi_requires_identity(self): + cur = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN) + for identity in (None, '', ' ', '\t', '\n'): + with self.subTest(identity=identity): + client = mock.MagicMock() + with self.assertRaisesRegex(ArgumentUsageError, 'non-empty --identity'): + self._run_update(cur, client=client, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=identity) + client.begin_update.assert_not_called() + + def test_migrate_to_sync_token_rejected(self): + cur = _fake_cr(has_identity=True, connection_state='Offline') + with self.assertRaises(ArgumentUsageError) as ctx: + self._run_update(cur, auth_type=AUTH_TYPE_SYNC_TOKEN) + self.assertIn('only migration to --auth-type ManagedIdentity is supported', + str(ctx.exception)) + + # ---- success paths: assert PATCH body shape --------------------------- + + def _extract_update_body(self, client): + # begin_update(resource_group_name=..., registry_name=..., + # connected_registry_name=..., connected_registry_update_parameters=...) + self.assertTrue(client.begin_update.called) + _, kwargs = client.begin_update.call_args + return kwargs['connected_registry_update_parameters'] + + def test_migrate_sync_token_to_mi_sends_identity(self): + for auth_type, state in ( + (None, 'Offline'), + (AUTH_TYPE_SYNC_TOKEN, 'Offline'), + (models.AuthType.SYNC_TOKEN, models.ConnectionState.OFFLINE)): + with self.subTest(auth_type=auth_type, state=state): + cur = _fake_cr(auth_type=auth_type, connection_state=state) + client = self._run_update(cur, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID) + serialized = self._extract_update_body(client).as_dict() + self.assertEqual(serialized['identity'], { + 'type': 'UserAssigned', 'userAssignedIdentities': {TEST_MSI_ID: {}}}) + self.assertEqual(serialized['properties']['syncProperties'], { + 'authType': AUTH_TYPE_MANAGED_IDENTITY}) + self.assertNotIn('parent', serialized['properties']) + + def test_migration_combines_with_ordinary_property_updates(self): + cur = _fake_cr(auth_type=AUTH_TYPE_SYNC_TOKEN, connection_state='Offline') + client = self._run_update( + cur, auth_type=AUTH_TYPE_MANAGED_IDENTITY, identity=TEST_MSI_ID, + sync_window='PT4H', log_level='Debug', garbage_collection_enabled=False, + add_client_token_list=['client-token'], add_notifications=['image:latest']) + serialized = self._extract_update_body(client).as_dict() + token_id = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/' + 'registries/{}/tokens/client-token'.format(TEST_SUB, TEST_RG, TEST_REGISTRY) + ) + self.assertEqual(serialized, { + 'identity': {'type': 'UserAssigned', 'userAssignedIdentities': {TEST_MSI_ID: {}}}, + 'properties': { + 'syncProperties': {'authType': AUTH_TYPE_MANAGED_IDENTITY, 'syncWindow': 'PT4H'}, + 'logging': {'logLevel': 'Debug'}, + 'garbageCollection': {'enabled': False}, + 'clientTokenIds': [token_id], + 'notificationsList': ['image:latest'], + }, + }) + client.begin_update.assert_called_once() + client.list.assert_not_called() + + def test_ordinary_update_preserves_auth_on_either_mode(self): + token_prefix = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/' + 'registries/{}/tokens/'.format(TEST_SUB, TEST_RG, TEST_REGISTRY) + ) + for auth_type in (None, AUTH_TYPE_SYNC_TOKEN, AUTH_TYPE_MANAGED_IDENTITY): + with self.subTest(auth_type=auth_type): + cur = _fake_cr(auth_type=auth_type, + has_identity=auth_type == AUTH_TYPE_MANAGED_IDENTITY, + connection_state='Online') + cur.client_token_ids = [token_prefix + 'old-token'] + cur.notifications_list = ['old:latest'] + client = self._run_update( + cur, add_client_token_list=['new-token'], remove_client_token_list=['old-token'], + sync_schedule='0 12 * * *', sync_window='PT4H', sync_message_ttl='P2D', + log_level='Information', sync_audit_logs_enabled='Enabled', + garbage_collection_enabled=False, garbage_collection_schedule='0 0 * * *', + add_notifications=['new:latest'], remove_notifications=['old:latest']) + serialized = self._extract_update_body(client).as_dict() + self.assertEqual(serialized, {'properties': { + 'syncProperties': { + 'schedule': '0 12 * * *', 'syncWindow': 'PT4H', 'messageTtl': 'P2D'}, + 'logging': {'logLevel': 'Information', 'auditLogStatus': 'Enabled'}, + 'garbageCollection': {'enabled': False, 'schedule': '0 0 * * *'}, + 'clientTokenIds': [token_prefix + 'new-token'], + 'notificationsList': ['new:latest'], + }}) + self.assertNotIn('identity', serialized) + self.assertNotIn('authType', serialized['properties']['syncProperties']) + client.begin_update.assert_called_once() + client.list.assert_not_called() + + +# --------------------------------------------------------------------------- +# get-settings: MI-flavored connection string +# --------------------------------------------------------------------------- + + +class TestConnectedRegistryGetSettingsMI(unittest.TestCase): + + def _invoke(self, cr, **kw): + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', + return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.acr_connected_registry_show', + return_value=cr): + return acr_connected_registry_get_settings( + cmd=_make_cmd(), client=mock.MagicMock(), + connected_registry_name=TEST_CR, registry_name=TEST_REGISTRY, + parent_protocol='https', resource_group_name=TEST_RG, **kw) + + def test_generate_password_rejected_on_mi(self): + cr = _fake_cr(has_identity=True) + with self.assertRaises(ArgumentUsageError): + self._invoke(cr, generate_password='1', yes=True) + + def test_missing_user_assigned_errors(self): + cr = _fake_cr(has_identity=True) + cr.identity.user_assigned_identities = None + with self.assertRaises(CLIError): + self._invoke(cr) + + def test_missing_client_id_errors(self): + cr = _fake_cr(has_identity=True, client_id=None) + with self.assertRaises(CLIError): + self._invoke(cr) + + def test_happy_path_returns_mi_connection_string(self): + cr = _fake_cr(has_identity=True, client_id='cid-happy') + result = self._invoke(cr) + self.assertIn('ManagedIdentityClientId=cid-happy', + result['ACR_REGISTRY_CONNECTION_STRING']) + self.assertNotIn('SyncTokenName', result['ACR_REGISTRY_CONNECTION_STRING']) + self.assertNotIn('SYNC_TOKEN_USER', result) + self.assertNotIn('SYNC_TOKEN_PASSWORD', result) + self.assertNotIn('ACR_MANAGED_IDENTITY_CLIENT_ID', result) + self.assertEqual(result['ACR_MANAGED_IDENTITY_RESOURCE_ID'], TEST_MSI_ID) + + def test_migrated_settings_report_attached_identity_despite_stale_token(self): + cr = _fake_cr(auth_type=models.AuthType.MANAGED_IDENTITY, has_identity=True, + token_id='/tokens/old-sync', client_id='cid-migrated') + cr.identity.user_assigned_identities = { + TEST_MSI_ID2: cr.identity.user_assigned_identities[TEST_MSI_ID]} + result = self._invoke(cr) + self.assertEqual(result['ACR_MANAGED_IDENTITY_RESOURCE_ID'], TEST_MSI_ID2) + self.assertIn('ManagedIdentityClientId=cid-migrated;', result['ACR_REGISTRY_CONNECTION_STRING']) + self.assertNotIn(TEST_MSI_ID2, result['ACR_REGISTRY_CONNECTION_STRING']) + self.assertNotIn('SyncToken', result['ACR_REGISTRY_CONNECTION_STRING']) + self.assertNotIn('SYNC_TOKEN_USER', result) + self.assertNotIn('SYNC_TOKEN_PASSWORD', result) + + def test_source_settings_use_get_without_token_or_credential_calls(self): + cr = _fake_cr(has_identity=True, client_id='cid-happy') + cr.name = 'name-returned-by-get' + client = mock.MagicMock() + client.get.return_value = cr + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.get_token_from_id') as token_lookup, \ + mock.patch(UPDATE_MODULE + '.cf_acr_tokens') as token_factory, \ + mock.patch('azure.cli.command_modules.acr._client_factory.cf_acr_token_credentials') as cred_factory, \ + mock.patch('azure.cli.command_modules.acr.token.acr_token_credential_generate') as generate, \ + mock.patch(UPDATE_MODULE + '.user_confirmation') as confirm: + result = acr_connected_registry_get_settings( + cmd=_make_cmd(), client=client, + connected_registry_name=TEST_CR, registry_name=TEST_REGISTRY, + parent_protocol='http', resource_group_name=TEST_RG) + client.get.assert_called_once_with(TEST_RG, TEST_REGISTRY, TEST_CR) + self.assertEqual(client.method_calls, [mock.call.get(TEST_RG, TEST_REGISTRY, TEST_CR)]) + token_lookup.assert_not_called() + token_factory.assert_not_called() + cred_factory.assert_not_called() + generate.assert_not_called() + confirm.assert_not_called() + self.assertEqual(result, { + 'ACR_MANAGED_IDENTITY_RESOURCE_ID': TEST_MSI_ID, + 'ACR_REGISTRY_CERTIFICATE_VOLUME': '/var/acr/certs', + 'ACR_REGISTRY_DATA_VOLUME': '/var/acr/data', + 'ACR_REGISTRY_CONNECTION_STRING': ( + 'ConnectedRegistryName={};ManagedIdentityClientId=cid-happy;' + 'ParentGatewayEndpoint=parent.example.com;ParentEndpointProtocol=https'.format(TEST_CR)), + 'ACR_REGISTRY_LOGIN_SERVER': ( + ''), + }) + + +class TestConnectedRegistryGetSettingsSyncToken(unittest.TestCase): + + def test_legacy_settings_passwords_endpoints_and_protocols(self): + token_id = ( + '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.ContainerRegistry/' + 'registries/{}/tokens/sync'.format(TEST_SUB, TEST_RG, TEST_REGISTRY)) + parent_id = '/connectedRegistries/parent' + for auth_type, parent, gateway, protocol, password, expected_protocol in ( + (None, None, 'parent.example.com', 'http', None, 'https'), + (AUTH_TYPE_SYNC_TOKEN, None, None, 'https', None, 'https'), + (AUTH_TYPE_SYNC_TOKEN, parent_id, '', 'http', None, 'http'), + (AUTH_TYPE_SYNC_TOKEN, parent_id, 'parent.example.com', 'https', None, 'https'), + (AUTH_TYPE_SYNC_TOKEN, None, 'parent.example.com', 'http', '1', 'https'), + (AUTH_TYPE_SYNC_TOKEN, parent_id, 'parent.example.com', 'http', '2', 'http')): + with self.subTest(auth_type=auth_type, parent=parent, gateway=gateway, + protocol=protocol, password=password): + cr = _fake_cr(auth_type=auth_type, token_id=token_id, gateway_endpoint=gateway) + cr.parent.id = parent + cmd = _make_cmd() + credentials = mock.MagicMock() + credentials.username = 'generated-sync' + credentials.passwords = [ + mock.Mock(value='test-only-password-1'), + mock.Mock(value='test-only-password-2'), + ] + credentials.passwords[0].name = 'password1' + credentials.passwords[1].name = 'password2' + with mock.patch(UPDATE_MODULE + '.validate_managed_registry', return_value=(None, TEST_RG)), \ + mock.patch(UPDATE_MODULE + '.acr_connected_registry_show', return_value=cr), \ + mock.patch(UPDATE_MODULE + '.user_confirmation') as confirm, \ + mock.patch('azure.cli.command_modules.acr._client_factory.cf_acr_token_credentials') as factory, \ + mock.patch('azure.cli.command_modules.acr.token.acr_token_credential_generate') as generate, \ + mock.patch(UPDATE_MODULE + '.LongRunningOperation') as lro: + lro.return_value.return_value = credentials + result = acr_connected_registry_get_settings( + cmd=cmd, client=mock.MagicMock(), + connected_registry_name=TEST_CR, registry_name=TEST_REGISTRY, + parent_protocol=protocol, generate_password=password, yes=True, + resource_group_name=TEST_RG) + username = credentials.username if password else 'sync' + expected_password = ('test-only-password-' + password if password else + '') + self.assertEqual(result, { + 'SYNC_TOKEN_USER': username, + 'SYNC_TOKEN_PASSWORD': expected_password, + 'ACR_REGISTRY_CERTIFICATE_VOLUME': '/var/acr/certs', + 'ACR_REGISTRY_DATA_VOLUME': '/var/acr/data', + 'ACR_REGISTRY_CONNECTION_STRING': ( + 'ConnectedRegistryName={};SyncTokenName={};SyncTokenPassword={};' + 'ParentGatewayEndpoint={};ParentEndpointProtocol={}'.format( + TEST_CR, username, expected_password, + gateway or '', expected_protocol)), + 'ACR_REGISTRY_LOGIN_SERVER': ( + ''), + }) + if password: + confirm.assert_called_once_with( + "Are you sure you want to generate a new sync token 'sync' password{}?".format(password), True) + factory.assert_called_once_with(cmd.cli_ctx) + generate.assert_called_once_with( + cmd, factory.return_value, TEST_REGISTRY, 'sync', + password1=password == '1', password2=password == '2', resource_group_name=TEST_RG) + lro.assert_called_once_with(cmd.cli_ctx) + lro.return_value.assert_called_once_with(generate.return_value) + else: + confirm.assert_not_called() + factory.assert_not_called() + generate.assert_not_called() + lro.assert_not_called() + + +if __name__ == '__main__': + unittest.main() diff --git a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connectedregistry_commands.py b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connectedregistry_commands.py index 67bdaaf8f30..8004ee2d91a 100644 --- a/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connectedregistry_commands.py +++ b/src/azure-cli/azure/cli/command_modules/acr/tests/latest/test_acr_connectedregistry_commands.py @@ -234,3 +234,158 @@ def test_acr_connectedregistry_dedicated_endpoint_not_enabled(self, resource_gro # Delete registry self.cmd('acr delete -n {registry_name} -g {rg} -y') + + @ResourceGroupPreparer() + @AllowLargeResponse(size_kb=99999) + def test_acr_connectedregistry_managed_identity(self): + # Managed-identity auth mode for connected registries. Recorded scenario is + # intentionally minimal (create + show + get-settings + delete) so the cassette + # does not depend on the SyncToken->ManagedIdentity migration. + # Client-side validation, the migration state machine, and MI-mode delete cleanup + # are covered by mock-based unit tests in test_acr_connected_registry_mi_unit.py. + # Note: This test does NOT import from azure.mgmt.containerregistry so the + # recording remains valid across future SDK model-namespace changes. + + self.kwargs.update({ + 'registry_name': self.create_random_name('clireg', 20), + 'cr_mi_name': 'crmiscen', + 'rg_loc': 'eastus', + 'sku': 'Premium', + 'identity_name': self.create_random_name('cr-mi-id', 20), + }) + + # Registry + data endpoint + abac (required for connected-registry). + self.cmd('acr create -n {registry_name} -g {rg} -l {rg_loc} --sku {sku} ' + '--role-assignment-mode rbac-abac', + checks=[self.check('name', '{registry_name}'), + self.check('sku.name', '{sku}'), + self.check('provisioningState', 'Succeeded'), + self.check('roleAssignmentMode', 'AbacRepositoryPermissions')]) + self.cmd('acr update -n {registry_name} -g {rg} --data-endpoint-enabled true', + checks=[self.check('dataEndpointEnabled', True), + self.check('roleAssignmentMode', 'AbacRepositoryPermissions')]) + + # User-assigned identity. + result = self.cmd('identity create --name {identity_name} -g {rg}').get_output_in_json() + self.kwargs['identity_id'] = result['id'] + self.kwargs['identity_client_id'] = result['clientId'] + + # --- Create with ManagedIdentity --- + self.cmd('acr connected-registry create -n {cr_mi_name} -r {registry_name} -g {rg} ' + '-m ReadOnly --auth-type ManagedIdentity --identity {identity_id}', + checks=[self.check('name', '{cr_mi_name}'), + self.check('mode', 'ReadOnly'), + self.check('provisioningState', 'Succeeded'), + self.check('parent.syncProperties.authType', 'ManagedIdentity'), + self.check('identity.type', 'userAssigned')]) + + # --- Show reflects MI --- + self.cmd('acr connected-registry show -n {cr_mi_name} -r {registry_name} -g {rg}', + checks=[self.check('parent.syncProperties.authType', 'ManagedIdentity'), + self.check('identity.type', 'userAssigned')]) + + # --- get-settings returns MI-flavored connection string --- + settings = self.cmd('acr connected-registry get-settings -n {cr_mi_name} -r {registry_name} ' + '-g {rg} --parent-protocol https').get_output_in_json() + connection_string = settings['ACR_REGISTRY_CONNECTION_STRING'] + self.assertIn( + 'ManagedIdentityClientId={};'.format(self.kwargs['identity_client_id']), + connection_string) + self.assertNotIn('SyncTokenName=', connection_string) + self.assertNotIn('SyncTokenPassword=', connection_string) + self.assertNotIn('SYNC_TOKEN_USER', settings) + self.assertNotIn('SYNC_TOKEN_PASSWORD', settings) + self.assertEqual(settings['ACR_MANAGED_IDENTITY_RESOURCE_ID'].lower(), + self.kwargs['identity_id'].lower()) + + # --- MI-mode delete (no sync token / scope map cleanup path) --- + self.cmd('acr connected-registry delete -n {cr_mi_name} -r {registry_name} -g {rg} -y') + self.cmd('acr delete -n {registry_name} -g {rg} -y') + # Shared RG: clean up the user-assigned identity too. + self.cmd('identity delete --name {identity_name} -g {rg}') + + @ResourceGroupPreparer(location='eastus') + @AllowLargeResponse(size_kb=99999) + def test_acr_connectedregistry_managed_identity_migration(self, resource_group_location): + self.kwargs.update({ + 'registry_name': self.create_random_name('clireg', 20), + 'cr_name': 'crmigration', + 'identity_name': self.create_random_name('cr-mi-id', 20), + 'rg_loc': resource_group_location, + 'repository': 'hello-world', + 'sync_schedule': '0 0/10 * * *', + 'notification': 'hello-world:tag:push', + }) + + self.cmd('acr create -n {registry_name} -g {rg} -l {rg_loc} --sku Premium ' + '--role-assignment-mode rbac-abac', + checks=[self.check('provisioningState', 'Succeeded'), + self.check('roleAssignmentMode', 'AbacRepositoryPermissions')]) + self.cmd('acr update -n {registry_name} -g {rg} --data-endpoint-enabled true', + checks=[self.check('dataEndpointEnabled', True), + self.check('roleAssignmentMode', 'AbacRepositoryPermissions')]) + + identity = self.cmd('identity create -n {identity_name} -g {rg} -l {rg_loc}').get_output_in_json() + self.kwargs['identity_id'] = identity['id'] + + self.cmd('acr connected-registry create -n {cr_name} -r {registry_name} -g {rg} ' + '--mode ReadOnly --auth-type SyncToken --repository {repository} --log-level Warning ' + '--sync-schedule "{sync_schedule}" --sync-window PT4H ' + '--notifications {notification} --gc-enabled false') + + # No agent is started, so the new registry is already offline and needs no deactivation. + before = self.cmd( + 'acr connected-registry show -n {cr_name} -r {registry_name} -g {rg}', + checks=[self.check('name', '{cr_name}'), + self.check('mode', 'ReadOnly'), + self.check('provisioningState', 'Succeeded'), + self.check('connectionState', 'Offline'), + self.check('activation.status', 'Inactive'), + self.check('parent.syncProperties.authType', 'SyncToken'), + self.exists('parent.syncProperties.tokenId'), + self.check('logging.logLevel', 'Warning'), + self.check('parent.syncProperties.schedule', '{sync_schedule}'), + self.check('parent.syncProperties.syncWindow', '4:00:00'), + self.check('notificationsList[0]', '{notification}'), + self.check('garbageCollection.enabled', False)]).get_output_in_json() + + self.cmd('acr connected-registry update -n {cr_name} -r {registry_name} -g {rg} ' + '--auth-type ManagedIdentity --identity {identity_id}', + checks=[self.check('provisioningState', 'Succeeded'), + self.check('parent.syncProperties.authType', 'ManagedIdentity')]) + + after = self.cmd( + 'acr connected-registry show -n {cr_name} -r {registry_name} -g {rg}', + checks=[self.check('provisioningState', 'Succeeded'), + self.check('connectionState', 'Offline'), + self.check('parent.syncProperties.authType', 'ManagedIdentity'), + self.check('identity.type', 'userAssigned', case_sensitive=False)]).get_output_in_json() + + assigned_identities = after['identity']['userAssignedIdentities'] + self.assertEqual({resource_id.lower() for resource_id in assigned_identities}, + {identity['id'].lower()}) + self.assertEqual(next(iter(assigned_identities.values()))['clientId'], identity['clientId']) + + for property_name in ('id', 'name', 'mode', 'logging', 'notificationsList', 'garbageCollection'): + self.assertEqual(after[property_name], before[property_name], property_name) + self.assertEqual(after['parent'].get('id'), before['parent'].get('id')) + for property_name in ('schedule', 'syncWindow', 'messageTtl'): + self.assertEqual(after['parent']['syncProperties'][property_name], + before['parent']['syncProperties'][property_name], property_name) + + settings = self.cmd( + 'acr connected-registry get-settings -n {cr_name} -r {registry_name} -g {rg} ' + '--parent-protocol https').get_output_in_json() + connection_string = settings['ACR_REGISTRY_CONNECTION_STRING'] + self.assertIn('ManagedIdentityClientId={};'.format(identity['clientId']), connection_string) + self.assertNotIn('SyncTokenName=', connection_string) + self.assertNotIn('SyncTokenPassword=', connection_string) + self.assertNotIn('SYNC_TOKEN_USER', settings) + self.assertNotIn('SYNC_TOKEN_PASSWORD', settings) + self.assertEqual(settings['ACR_MANAGED_IDENTITY_RESOURCE_ID'].lower(), identity['id'].lower()) + + self.cmd('acr connected-registry delete -n {cr_name} -r {registry_name} -g {rg} --cleanup -y') + self.cmd('identity show -n {identity_name} -g {rg}', + checks=self.check('clientId', identity['clientId'])) + self.cmd('acr delete -n {registry_name} -g {rg} -y') + self.cmd('identity delete -n {identity_name} -g {rg}')