From 477b02c440edee2439009227e8a5bb90d566aa27 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Sep 2026 07:41:04 +0000 Subject: [PATCH 1/3] Initial plan From e3120f57d3c2a864fa9d47a2e41742328be1af80 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Sep 2026 07:45:01 +0000 Subject: [PATCH 2/3] Report actual vault name option in keyvault validator error messages Co-authored-by: isra-fel <11371776+isra-fel@users.noreply.github.com> --- .../command_modules/keyvault/_validators.py | 19 ++++++-- .../keyvault/tests/latest/test_validators.py | 48 +++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py diff --git a/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py b/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py index 668b83ae9a0..3a62ef93ee4 100644 --- a/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py @@ -131,14 +131,27 @@ def process_hsm_name(ns): ns.hsm_name = ns.identifier +def _get_vault_name_options(ns): + """Get the option string of the vault name argument registered for the current command, + as it can be either --vault-name or --name/-n.""" + default_options = '--vault-name' + cmd = getattr(ns, 'cmd', None) + argument = cmd.arguments.get('vault_name', None) if cmd else None + options_list = argument.options_list if argument else None + if not options_list: + return default_options + return '/'.join([str(option) for option in options_list]) + + def validate_vault_name_and_hsm_name(ns): vault_name = getattr(ns, 'vault_name', None) hsm_name = getattr(ns, 'hsm_name', None) + vault_name_options = _get_vault_name_options(ns) if vault_name and hsm_name: - raise CLIError('--vault-name and --hsm-name are mutually exclusive.') + raise CLIError('{} and --hsm-name are mutually exclusive.'.format(vault_name_options)) if not vault_name and not hsm_name: - raise CLIError('Please specify --vault-name or --hsm-name.') + raise CLIError('Please specify {} or --hsm-name.'.format(vault_name_options)) # PARAMETER NAMESPACE VALIDATORS @@ -426,7 +439,7 @@ def validate_deleted_vault_or_hsm_name(cmd, ns): hsm_name = getattr(ns, 'hsm_name', None) if not vault_name and not hsm_name: - raise CLIError('Please specify --vault-name or --hsm-name.') + raise CLIError('Please specify {} or --hsm-name.'.format(_get_vault_name_options(ns))) if vault_name: resource_name = vault_name diff --git a/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py b/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py new file mode 100644 index 00000000000..d96fcf52d65 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py @@ -0,0 +1,48 @@ +# -------------------------------------------------------------------------------------------- +# 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 knack.arguments import CLICommandArgument +from knack.util import CLIError + +from azure.cli.command_modules.keyvault._validators import validate_vault_name_and_hsm_name + + +class _Command: + def __init__(self, vault_name_options): + self.arguments = { + 'vault_name': CLICommandArgument('vault_name', options_list=vault_name_options) + } + + +class _Namespace: + def __init__(self, vault_name_options=None, vault_name=None, hsm_name=None): + if vault_name_options: + self.cmd = _Command(vault_name_options) + self.vault_name = vault_name + self.hsm_name = hsm_name + + +class KeyVaultValidatorsTest(unittest.TestCase): + def test_validate_vault_name_and_hsm_name(self): + # the error message should match the option registered for the command + with self.assertRaisesRegex(CLIError, r'Please specify --name/-n or --hsm-name\.'): + validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--name', '-n'])) + + with self.assertRaisesRegex(CLIError, r'--name/-n and --hsm-name are mutually exclusive\.'): + validate_vault_name_and_hsm_name( + _Namespace(vault_name_options=['--name', '-n'], vault_name='vault', hsm_name='hsm')) + + with self.assertRaisesRegex(CLIError, r'Please specify --vault-name or --hsm-name\.'): + validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--vault-name'])) + + # no exception when just one of them is specified + validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--name', '-n'], vault_name='vault')) + validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--name', '-n'], hsm_name='hsm')) + + +if __name__ == '__main__': + unittest.main() From d2955b23fde15d7ca6abf7be350c5f4a6b20096f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Sep 2026 07:45:54 +0000 Subject: [PATCH 3/3] Harden option lookup and extend validator tests Co-authored-by: isra-fel <11371776+isra-fel@users.noreply.github.com> --- .../cli/command_modules/keyvault/_validators.py | 3 ++- .../keyvault/tests/latest/test_validators.py | 14 +++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py b/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py index 3a62ef93ee4..87fd84d4bda 100644 --- a/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py @@ -136,7 +136,8 @@ def _get_vault_name_options(ns): as it can be either --vault-name or --name/-n.""" default_options = '--vault-name' cmd = getattr(ns, 'cmd', None) - argument = cmd.arguments.get('vault_name', None) if cmd else None + arguments = getattr(cmd, 'arguments', None) or {} + argument = arguments.get('vault_name', None) options_list = argument.options_list if argument else None if not options_list: return default_options diff --git a/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py b/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py index d96fcf52d65..9d354c75740 100644 --- a/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py +++ b/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_validators.py @@ -8,7 +8,10 @@ from knack.arguments import CLICommandArgument from knack.util import CLIError -from azure.cli.command_modules.keyvault._validators import validate_vault_name_and_hsm_name +from azure.cli.command_modules.keyvault._validators import ( + validate_deleted_vault_or_hsm_name, + validate_vault_name_and_hsm_name, +) class _Command: @@ -39,10 +42,19 @@ def test_validate_vault_name_and_hsm_name(self): with self.assertRaisesRegex(CLIError, r'Please specify --vault-name or --hsm-name\.'): validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--vault-name'])) + # fall back to --vault-name when the vault name argument can't be resolved + with self.assertRaisesRegex(CLIError, r'Please specify --vault-name or --hsm-name\.'): + validate_vault_name_and_hsm_name(_Namespace()) + # no exception when just one of them is specified validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--name', '-n'], vault_name='vault')) validate_vault_name_and_hsm_name(_Namespace(vault_name_options=['--name', '-n'], hsm_name='hsm')) + def test_validate_deleted_vault_or_hsm_name(self): + ns = _Namespace(vault_name_options=['--name', '-n']) + with self.assertRaisesRegex(CLIError, r'Please specify --name/-n or --hsm-name\.'): + validate_deleted_vault_or_hsm_name(ns.cmd, ns) + if __name__ == '__main__': unittest.main()