Skip to content

Commit

Permalink
[ACR] az acr create: Add validation for registry name to support do…
Browse files Browse the repository at this point in the history
…main name label (#30404)
  • Loading branch information
trisavo-msft authored Dec 17, 2024
1 parent d978740 commit 3fb76a9
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/azure-cli/azure/cli/command_modules/acr/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
ACR_AUDIENCE_RESOURCE_NAME = "containerregistry"

# Regex pattern to validate that registry name is alphanumeric and between 5 and 50 characters
# Dashes "-" are allowed to accomodate for domain name label scope, but is blocked on registry creation "acr create"
ACR_NAME_VALIDATION_REGEX = r'^[a-zA-Z0-9-]{5,50}$'

ALLOWED_TASK_FILE_TYPES = ('.yaml', '.yml', '.toml', '.json', '.sh', '.bash', '.zsh', '.ps1',
Expand Down
11 changes: 11 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acr/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ def validate_registry_name(cmd, namespace):
if pos > 0:
logger.warning("The login server endpoint suffix '%s' is automatically omitted.", acr_suffix)
namespace.registry_name = registry[:pos]
registry = registry[:pos]
# If registry contains '-' due to Domain Name Label Scope,
# ex: "myregistry-dnlhash123.azurecr.io", strip "-dnlhash123"
dnl_hash = registry.find("-")
if registry and dnl_hash > 0:
logger.warning(
"The domain name label suffix '%s' is automatically omitted. Registry name is %s.",
registry[dnl_hash:],
registry[:dnl_hash])
namespace.registry_name = registry[:dnl_hash]

registry = namespace.registry_name
if not re.match(ACR_NAME_VALIDATION_REGEX, registry):
raise InvalidArgumentValueError(BAD_REGISTRY_NAME)
Expand Down
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/acr/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def acr_create(cmd,
if re.match(r'\w*[A-Z]\w*', registry_name):
raise InvalidArgumentValueError("argument error: Registry name must use only lowercase.")

if re.match(r'\w*[-]\w*', registry_name):
raise InvalidArgumentValueError("argument error: Registry name cannot contain dashes.")

Registry, Sku, NetworkRuleSet = cmd.get_models('Registry', 'Sku', 'NetworkRuleSet')
registry = Registry(location=location, sku=Sku(name=sku), admin_user_enabled=admin_enabled,
zone_redundancy=zone_redundancy, tags=tags)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# --------------------------------------------------------------------------------------------

from azure.cli.testsdk.scenario_tests import AllowLargeResponse
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer, KeyVaultPreparer, record_only
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer, KeyVaultPreparer, record_only, live_only
from azure.cli.command_modules.acr.custom import DEF_DIAG_SETTINGS_NAME_TEMPLATE


Expand Down Expand Up @@ -713,6 +713,21 @@ def test_acr_with_anonymous_pull(self, resource_group, resource_group_location):
self.cmd('acr update --name {registry_name} --resource-group {rg} --anonymous-pull-enabled false',
checks=[self.check('anonymousPullEnabled', False)])

@ResourceGroupPreparer()
@live_only()
def test_acr_create_invalid_name(self, resource_group):
from azure.cli.core.azclierror import InvalidArgumentValueError

# Block registry creation if there is '-'.
self.kwargs.update({
'registry_name': self.create_random_name('testreg', 20) + '-' + self.create_random_name('dnlhash', 20)
})

with self.assertRaises(Exception) as ex:
self.cmd('acr create --name {registry_name} --resource-group {rg} --sku premium -l eastus')

self.assertTrue(InvalidArgumentValueError, ex.exception)

@ResourceGroupPreparer(location='eastus2')
def test_acr_with_private_endpoint(self, resource_group):
self.kwargs.update({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import unittest
from types import SimpleNamespace
from unittest.mock import Mock
from azure.cli.core.cloud import HARD_CODED_CLOUD_LIST
from azure.cli.command_modules.acr._validators import validate_registry_name

class AcrValidatorsTests(unittest.TestCase):
def test_registry_name_with_dnl_suffix(self):
acr_supported_clouds = [cloud for cloud in HARD_CODED_CLOUD_LIST if cloud.name != 'AzureGermanCloud']
for hard_coded_cloud in acr_supported_clouds:
namespace = SimpleNamespace(
**{
"registry_name": "myacr-dnlhash123",
}
)
cmd = Mock(cli_ctx=Mock(cloud=hard_coded_cloud))
validate_registry_name(cmd, namespace)
self.assertEqual(namespace.registry_name, 'myacr')

def test_registry_name_with_dnl_suffix_loginserver(self):
namespace = SimpleNamespace(
**{
"registry_name": "myacr-dnlhash123.azurecr.io",
}
)
azure_public_cloud = HARD_CODED_CLOUD_LIST[0]
cmd = Mock(cli_ctx=Mock(cloud=azure_public_cloud))
validate_registry_name(cmd, namespace)
self.assertEqual(namespace.registry_name, 'myacr')

0 comments on commit 3fb76a9

Please sign in to comment.