diff --git a/src/azure-cli/azure/cli/command_modules/keyvault/_params.py b/src/azure-cli/azure/cli/command_modules/keyvault/_params.py index 7be337469d7..2e758b43d7d 100644 --- a/src/azure-cli/azure/cli/command_modules/keyvault/_params.py +++ b/src/azure-cli/azure/cli/command_modules/keyvault/_params.py @@ -19,7 +19,7 @@ from azure.cli.command_modules.keyvault._completers import ( get_keyvault_name_completion_list, get_keyvault_version_completion_list) from azure.cli.command_modules.keyvault._validators import ( - datetime_type, certificate_type, + datetime_type, certificate_type, validate_retention_days_on_creation, get_vault_base_url_type, get_hsm_base_url_type, validate_key_import_type, validate_key_import_source, validate_key_type, validate_policy_permissions, validate_principal, validate_resource_group_name, validate_x509_certificate_chain, @@ -166,7 +166,9 @@ class CLISecurityDomainOperation(str, Enum): c.argument('no_self_perms', arg_type=get_three_state_flag(), help='[Vault Only] Don\'t add permissions for the current user/service principal in the new vault.') c.argument('location', validator=get_default_location_from_resource_group) - c.argument('retention_days', help='Soft delete data retention days. It accepts >=7 and <=90.', default='90') + c.argument('retention_days', validator=validate_retention_days_on_creation, + help='Soft delete data retention days. It accepts >=7 and <=90. ' + 'Defaults to 90 for keyvault creation. Required for MHSM creation') with self.argument_context('keyvault create', arg_group='Network Rule') as c: c.argument('network_acls', type=validate_file_or_dict, 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 5c66fca3d29..a4e6b8c47d8 100644 --- a/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py +++ b/src/azure-cli/azure/cli/command_modules/keyvault/_validators.py @@ -220,6 +220,18 @@ def validate_vault_name_and_hsm_name(ns): # PARAMETER NAMESPACE VALIDATORS +def validate_retention_days_on_creation(ns): + # If customer has specified retention days, nothing to do + if ns.retention_days: + return + # If customer has not specified retention days, + # ask for mandatory retention days for MHSM creation, else set to default '90' for keyvault creation + if getattr(ns, 'hsm_name', None): + raise RequiredArgumentMissingError("--retention-days is required for MHSM creation.") + if getattr(ns, 'vault_name', None): + ns.retention_days = '90' + + def get_attribute_validator(name, attribute_class, create=False): def validator(ns): ns_dict = ns.__dict__ diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_0.cer b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_0.cer new file mode 100644 index 00000000000..498a5203949 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_0.cer @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgIUQ9MFlEMQ93dk3SeqBPWTOzk4+4AwDQYJKoZIhvcNAQEL +BQAwYDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNIMREwDwYDVQQHDAhNaW5nSGFu +ZzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ4wDAYDVQQDDAV5 +aXNoaTAeFw0yMTA5MjIwODA0NDdaFw0yMjA5MjIwODA0NDdaMGAxCzAJBgNVBAYT +AkNOMQswCQYDVQQIDAJTSDERMA8GA1UEBwwITWluZ0hhbmcxITAfBgNVBAoMGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFeWlzaGkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2XSIJePQXJX1wOYTA5vjQ4WSm8f4Vwk0f +n+JcBdCP793fg8ZilhRrGVa9rIgW0tvFgdBBnnvFdnk+ZfmOYKd1CazKZhVAQVcP +hFUy/XUx+yf+1V4PlBdDyqRnmJxAL50G97vu/7ULAmDfIuq+ox0H758dXOiCbwX8 +bluqjmbp2BWk/75pNsjbX2XdyU4Y4zPy09RlloboA4rB+2oeE8dZwpwL8ryU/vzi ++FCRqK0wavax4eY/KFktNh22/dB3ZgFYwwASsx6JQ3Z73pufdrMUE93vhvq0SONQ +jBedH00RfhNE1vgl5dg++O3K6aNdA3icykgWExn3Zl4AbjZx67INAgMBAAGjUzBR +MB0GA1UdDgQWBBTkqx6/uAIe4Ek6Cbp0/+FOKkmgKjAfBgNVHSMEGDAWgBTkqx6/ +uAIe4Ek6Cbp0/+FOKkmgKjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQCABHyOZ/52JPyHItAA6Uk4SovbYvplcbfjGAhMeKjpfAgZQRfJJYbPLu7p ++eo8mZrosPMguSRJMwK0Wk9mIQqXgMXRXDwaR8lGx731NG+IUM2gVowGB3r7KYVx +YLFjFW9M3mwm4Wr5DXKvTjkfz2bkg4vqDN1up4g+nLnPVbe8OEiUKQiTP2UY+qlo +nLCGQ0RVwKT9bW/JN4oDYX4t3yTXzioFiJMbEIbLZM2AdNSdyTb6LJALecxRFqDC +DOSO9HTJ9vEZjlLWaw+EK9Iuuyl4sXkRY69Sc6WswhvzcVcYEWNgwBA3N3QXur25 +SsLNr/2G4VSqOoHtCH2Ved50S4OX +-----END CERTIFICATE----- diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_1.cer b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_1.cer new file mode 100644 index 00000000000..dad879dfd08 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_1.cer @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjzCCAnegAwIBAgIUDLVCbKxtJ9+a50F9z7kLNAnJyO8wDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5nSGFpMSEwHwYDVQQKDBhJ +bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCVlpc2hpV2FuZzAeFw0y +MTA5MjIwODA1MTVaFw0yMjA5MjIwODA1MTVaMFcxCzAJBgNVBAYTAkNOMREwDwYD +VQQIDAhTaGFuZ0hhaTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk +MRIwEAYDVQQDDAlZaXNoaVdhbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCcdv0prbzQQFxRF8HJF4wVVAjrb99/s2bJlb6zyUUYmwfjTPtKU2b0Yu5d +pZtl1Xvd/fkmlSB8zxv0GkBJBR2azTtI07ZLOmZ75gwnjJA7ouF2kcqPRFHDY0YI +3QQbfZZmjH56qJg5d7GqO+P6Po1l5JHecleUvb6uzt8jhyxsyZlz/aU92qfCtEhM +w/kYVIqcBlQSGdj4jGcJUZasd/hjjiST41QFrtTIu6N3BLw2L18qgTTqF9iyQvR2 +QCMZCoR4rHOqWEu2v/tShjlYzaNi0u6PdM5OeQX4+3OrFzSFiBetTZffhif8luB2 +qefy3ehC/Uz8kujMRgNI4n1wW75pAgMBAAGjUzBRMB0GA1UdDgQWBBT0LN/7UzMc +ZvnspQNZbCyr8bYVkTAfBgNVHSMEGDAWgBT0LN/7UzMcZvnspQNZbCyr8bYVkTAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQARbFsTdQeqspyHmowz +vZxSMj+rYG2vaykb4cRyvCUpPdoMTs4dC/6ptb/YptgsSfbd1RxtFxfm8TbHSCqQ +56lz6a48NCtkyKoUJgk435xbU8iy7rHvvbp/fbCaY6q8liM4yteeuHVElrxJ3NRs +/1aCv+23NdeJeAlmNoQkShSwW7r4hS0z2mUEXNTzRi4yIc2bcXP/GuM5TFb0J4VH +GXzWOdenOvBmvrcRHTaY0tZObTq3os6X+YkpuXUMXwAhEjnqpDXQzSaEptZysUi4 +rj+DStjvTSV4WEkzMOfafb2RGHmhHW4rTY2QKntntTpoIKjXEVIsn///0YWsO9K7 +V99f +-----END CERTIFICATE----- diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_2.cer b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_2.cer new file mode 100644 index 00000000000..1de74ea70fc --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/certs/cert_2.cer @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUNGJjjAu1hi8wplMT0LN8u8XXioYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQ04xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTA5MjIwODA1NDZaFw0yMjA5 +MjIwODA1NDZaMEUxCzAJBgNVBAYTAkNOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDWgTcxu1umenddoUtCW1Uh8esc52YmWVDPTYUF3A7p +txM3XR2CNxfQi7bW0lZyY6jTzEpfP0xVlEl7KmnAI9ESwHnF6bTn2aN26muQLGrt +w38GqZxm7nPIRvXaPaWXJithiPnmcHrdzM8BjkvCQwT82WZNIY8b8B6u5TDpTDpF +SA7o/0ZMkl4oxprbFUBn+7beD6Tlj9RruQoSyf8velYavoIDkBFP6IkG8ij0Q1JT +GlSt9BxhD37q0FDZRTC5v2ndV5qFMiJHyJHxDcuw6LCEuy7eXiIjqG5XDn/RkmfH +lpZxObdt2QDEprGwJPP9KeMo1ahM6Wwy2p5zeKxazI05AgMBAAGjUzBRMB0GA1Ud +DgQWBBQwTO5TqlyS9fL5FODOc8sDW2xJjTAfBgNVHSMEGDAWgBQwTO5TqlyS9fL5 +FODOc8sDW2xJjTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBW +145H+S25zGRMmKNxecs/pIjowdkbs1xfwJX8diVP3r64qnx4K0xm5f2IC+9uc0AX +zQHWCMii3C7Nn/MxMZMp5Ab6VdMNTUYfsQQAR+U45QKhGRMfxaVphplr/GR+8vDI +M72YD6icIOfXOlQr0Nyppu2A5KFuugf7L3jZks/SkGIDbSOGlQpBeISERXiDWDqX +WZ4x8T7nleya5pkpDJ3gfn+EIuX3kXrQSqHcEi+jXmEkvxOgzJJEcUGUJ5nFjiVU +/NK7nDnxLL7s8O9WO8QSsdxnPIa+p6ZsM9V9ueQ900y3SS3JeXK41tzyhF+NuyrC +yCB5XL2H17sKnGdJYaH5 +-----END CERTIFICATE----- diff --git a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_private_endpoint_commands.py b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_private_endpoint_commands.py index 6fb13832e89..925e49f38cd 100644 --- a/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_private_endpoint_commands.py +++ b/src/azure-cli/azure/cli/command_modules/network/tests/latest/test_private_endpoint_commands.py @@ -11,7 +11,7 @@ from azure.core.exceptions import HttpResponseError from azure.cli.testsdk import ( - ScenarioTest, ResourceGroupPreparer, StorageAccountPreparer, KeyVaultPreparer, live_only, record_only) + ScenarioTest, ResourceGroupPreparer, StorageAccountPreparer, KeyVaultPreparer, ManagedHSMPreparer, live_only, record_only) from azure.cli.core.util import parse_proxy_resource_id, CLIError from azure.cli.command_modules.rdbms.tests.latest.test_rdbms_commands import ServerPreparer @@ -20,7 +20,7 @@ from azure.cli.testsdk.scenario_tests.utilities import is_text_payload TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..')) - +KV_CERTS_DIR = os.path.join(TEST_DIR, 'certs') class RedisCacheCredentialReplacer(RecordingProcessor): def process_response(self, response): @@ -55,20 +55,17 @@ def test_private_link_resource_keyvault(self, resource_group, key_vault): checks=self.check('@[0].properties.groupId', 'vault')) @ResourceGroupPreparer(name_prefix='cli_test_hsm_plr_rg') - def test_mhsm_private_link_resource(self, resource_group): + @ManagedHSMPreparer(name_prefix='cli-test-hsm-plr-', certs_path=KV_CERTS_DIR, location='centraluseuap') + def test_mhsm_private_link_resource(self, resource_group, managed_hsm): self.kwargs.update({ - 'hsm': self.create_random_name('cli-test-hsm-plr-', 24), + 'hsm': managed_hsm, 'loc': 'centraluseuap' }) - self.cmd('keyvault create --hsm-name {hsm} -g {rg} -l {loc} ' - '--administrators "3707fb2f-ac10-4591-a04f-8b0d786ea37d"') self.cmd('network private-link-resource list ' '--name {hsm} ' '-g {rg} ' '--type microsoft.keyvault/managedHSMs', checks=self.check('@[0].properties.groupId', 'managedhsm')) - self.cmd('keyvault delete --hsm-name {hsm} -g {rg}') - self.cmd('keyvault purge --hsm-name {hsm} -l {loc}') @ResourceGroupPreparer(name_prefix='cli_test_keyvault_pe') @KeyVaultPreparer(name_prefix='cli-test-kv-pe-', location='centraluseuap') @@ -176,21 +173,21 @@ def test_private_endpoint_connection_keyvault(self, resource_group): self.cmd('network private-endpoint-connection delete --id {kv_pe_id} -y') @ResourceGroupPreparer(name_prefix='cli_test_hsm_pe') - def test_hsm_private_endpoint_connection2(self, resource_group): + @ManagedHSMPreparer(name_prefix='cli-test-hsm-pe-', certs_path=KV_CERTS_DIR, location='uksouth') + def test_hsm_private_endpoint_connection2(self, resource_group, managed_hsm): self.kwargs.update({ - 'hsm': self.create_random_name('cli-test-hsm-pe-', 24), - 'loc': 'westus3', + 'hsm': managed_hsm, + 'loc': 'uksouth', 'vnet': self.create_random_name('cli-vnet-', 24), 'subnet': self.create_random_name('cli-subnet-', 24), 'pe': self.create_random_name('cli-pe-', 24), 'pe_connection': self.create_random_name('cli-pec-', 24), - 'rg': resource_group + 'rg': resource_group, + 'subscription_id': self.get_subscription_id(), }) # Prepare hsm and network - hsm = self.cmd('keyvault create --hsm-name {hsm} -g {rg} -l {loc} ' - '--administrators "3707fb2f-ac10-4591-a04f-8b0d786ea37d"').get_output_in_json() - self.kwargs['hsm_id'] = hsm['id'] + self.kwargs['hsm_id'] = f"/subscriptions/{self.kwargs['subscription_id']}/resourceGroups/{resource_group}/providers/Microsoft.KeyVault/managedHSMs/{managed_hsm}" self.cmd('network vnet create ' '-n {vnet} ' '-g {rg} ' @@ -270,8 +267,6 @@ def test_hsm_private_endpoint_connection2(self, resource_group): # clear resources self.cmd('network private-endpoint delete -g {rg} -n {pe}') - self.cmd('keyvault delete --hsm-name {hsm} -g {rg}') - self.cmd('keyvault purge --hsm-name {hsm} -l {loc}') class NetworkPrivateLinkStorageAccountScenarioTest(ScenarioTest):