@@ -1398,6 +1398,135 @@ def test_appgw_with_tcp(self, resource_group):
13981398
13991399 self.cmd('network application-gateway delete --name {appgw} --resource-group {rg}')
14001400
1401+ class NetworkAppGatewaySslCertManagedHsmScenarioTest(ScenarioTest):
1402+
1403+ @ResourceGroupPreparer(name_prefix='cli_test_ag_ssl_cert_hsm', location='uksouth')
1404+ def test_network_app_gateway_ssl_cert_managed_hsm(self, resource_group):
1405+ logged_in_user = self.cmd('ad signed-in-user show').get_output_in_json()
1406+ init_admin = logged_in_user['id'] if logged_in_user is not None else ''
1407+
1408+ self.kwargs.update({
1409+ 'ag': 'ag-hsm-test',
1410+ 'ip': 'pip-hsm-test',
1411+ 'identity': 'id-hsm-test',
1412+ 'hsm_name': self.create_random_name('clihsm', 24),
1413+ 'init_admin': init_admin,
1414+ 'cert_name': 'hsmSslCert',
1415+ 'cert_name2': 'hsmSslCert2',
1416+ })
1417+
1418+ # create managed identity
1419+ identity_result = self.cmd('identity create -g {rg} -n {identity}').get_output_in_json()
1420+ self.kwargs['identity_id'] = identity_result['id']
1421+ self.kwargs['identity_principal'] = identity_result['principalId']
1422+
1423+ # create Managed HSM
1424+ self.cmd('keyvault create --hsm-name {hsm_name} -g {rg} -l uksouth '
1425+ '--administrators {init_admin} --retention-days 7')
1426+
1427+ # activate HSM by downloading security domain
1428+ cert_dir = os.path.join(TEST_DIR, 'certs')
1429+ tmp_dir = tempfile.mkdtemp()
1430+ self.kwargs.update({
1431+ 'sd_cert0': os.path.join(cert_dir, 'cert_0.cer').replace('\\', '\\\\'),
1432+ 'sd_cert1': os.path.join(cert_dir, 'cert_1.cer').replace('\\', '\\\\'),
1433+ 'sd_cert2': os.path.join(cert_dir, 'cert_2.cer').replace('\\', '\\\\'),
1434+ 'security_domain': os.path.join(tmp_dir, 'sd.json').replace('\\', '\\\\'),
1435+ })
1436+ self.cmd('keyvault security-domain download --hsm-name {hsm_name} '
1437+ '--sd-wrapping-keys {sd_cert0} {sd_cert1} {sd_cert2} '
1438+ '--sd-quorum 2 --security-domain-file {security_domain}')
1439+
1440+ # grant signed-in user and identity access to create keys in HSM
1441+ from unittest import mock
1442+ with mock.patch('azure.cli.command_modules.keyvault.custom._gen_guid', side_effect=self.create_guid):
1443+ self.cmd('keyvault role assignment create --hsm-name {hsm_name} '
1444+ '--role "Managed HSM Crypto User" '
1445+ '--assignee {init_admin} --scope /keys')
1446+ self.cmd('keyvault role assignment create --hsm-name {hsm_name} '
1447+ '--role "Managed HSM Crypto User" '
1448+ '--assignee {identity_principal} --scope /keys')
1449+
1450+ # create keys in Managed HSM
1451+ kid = self.cmd('keyvault key create --hsm-name {hsm_name} -n mykey1'
1452+ ).get_output_in_json()['key']['kid']
1453+ kid2 = self.cmd('keyvault key create --hsm-name {hsm_name} -n mykey2'
1454+ ).get_output_in_json()['key']['kid']
1455+ self.kwargs.update({
1456+ 'hsm_key_id': kid,
1457+ 'hsm_key_id2': kid2,
1458+ })
1459+
1460+ # read public cert data from existing test cert file
1461+ cert_file = os.path.join(TEST_DIR, 'certs', 'cert_0.cer')
1462+ with open(cert_file, 'r') as f:
1463+ lines = f.read().strip().split('\n')
1464+ pub_cert_data = ''.join(l.strip() for l in lines if not l.startswith('-----'))
1465+ self.kwargs['pub_cert_data'] = pub_cert_data
1466+
1467+ # create public IP and application gateway with identity
1468+ self.cmd('network public-ip create -g {rg} -n {ip} --sku Standard')
1469+ self.cmd('network application-gateway create -g {rg} -n {ag} '
1470+ '--sku Standard_v2 --public-ip-address {ip} '
1471+ '--identity {identity_id} --priority 1001 --no-wait')
1472+ self.cmd('network application-gateway wait -g {rg} -n {ag} --exists')
1473+
1474+ # test validation: --hsm key-id without public-cert-data should fail
1475+ self.cmd('network application-gateway ssl-cert create -g {rg} --gateway-name {ag} '
1476+ '-n badCert --hsm key-id={hsm_key_id}',
1477+ expect_failure=True)
1478+
1479+ # test ssl-cert create with --hsm key-id and public-cert-data
1480+ self.cmd('network application-gateway ssl-cert create -g {rg} --gateway-name {ag} '
1481+ '-n {cert_name} --hsm key-id={hsm_key_id} public-cert-data={pub_cert_data}',
1482+ checks=[
1483+ self.check('name', '{cert_name}'),
1484+ self.check('hsm.keyId', '{hsm_key_id}'),
1485+ ])
1486+
1487+ # test ssl-cert show returns hsm block
1488+ self.cmd('network application-gateway ssl-cert show -g {rg} --gateway-name {ag} '
1489+ '-n {cert_name}',
1490+ checks=[
1491+ self.check('name', '{cert_name}'),
1492+ self.check('hsm.keyId', '{hsm_key_id}'),
1493+ self.exists('hsm'),
1494+ ])
1495+
1496+ # test ssl-cert update to change hsm key-id
1497+ self.cmd('network application-gateway ssl-cert update -g {rg} --gateway-name {ag} '
1498+ '-n {cert_name} --hsm key-id={hsm_key_id2} public-cert-data={pub_cert_data}',
1499+ checks=[
1500+ self.check('name', '{cert_name}'),
1501+ self.check('hsm.keyId', '{hsm_key_id2}'),
1502+ ])
1503+
1504+ # test ssl-cert list includes the hsm cert
1505+ self.cmd('network application-gateway ssl-cert list -g {rg} --gateway-name {ag}',
1506+ checks=[
1507+ self.check('length(@)', 1),
1508+ self.check('[0].name', '{cert_name}'),
1509+ self.check('[0].hsm.keyId', '{hsm_key_id2}'),
1510+ ])
1511+
1512+ # test ssl-cert create a second hsm cert
1513+ self.cmd('network application-gateway ssl-cert create -g {rg} --gateway-name {ag} '
1514+ '-n {cert_name2} --hsm key-id={hsm_key_id} public-cert-data={pub_cert_data}',
1515+ checks=[
1516+ self.check('name', '{cert_name2}'),
1517+ self.check('hsm.keyId', '{hsm_key_id}'),
1518+ ])
1519+ self.cmd('network application-gateway ssl-cert list -g {rg} --gateway-name {ag}',
1520+ checks=[self.check('length(@)', 2)])
1521+
1522+ # test ssl-cert delete
1523+ self.cmd('network application-gateway ssl-cert delete -g {rg} --gateway-name {ag} '
1524+ '-n {cert_name2} --no-wait')
1525+ self.cmd('network application-gateway wait -g {rg} -n {ag} --updated')
1526+ self.cmd('network application-gateway ssl-cert list -g {rg} --gateway-name {ag}',
1527+ checks=[self.check('length(@)', 1)])
1528+
1529+
14011530class NetworkAppGatewaySubresourceScenarioTest(ScenarioTest):
14021531
14031532 def _create_ag(self):
0 commit comments