-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[keyvault-preview]
az keyvault region add/remove/list/wait
: Support…
… MHSM multi-region HA (#4131) * create a new extension for keyvault preview features * version 1.0.0 for GEO replication * add `az keyvault region add/remove/list/wait` * fix * code owner * change `--region-names` to `--region-name` * refine help * update service_name.json
- Loading branch information
Showing
54 changed files
with
15,656 additions
and
2 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.. :changelog: | ||
Release History | ||
=============== | ||
|
||
1.0.0 | ||
++++++ | ||
* Support managed HSM Geo replication. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Microsoft Azure CLI 'keyvault-preview' Extension # | ||
|
||
This package is for the 'keyvault-preview' extension. | ||
|
||
## How to use ## | ||
|
||
Install this extension using the below CLI command | ||
|
||
```sh | ||
az extension add --name keyvault-preview | ||
``` | ||
|
||
### Included Features ### | ||
|
||
#### Feature description #### | ||
|
||
```sh | ||
az keyvault XXX | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azure.cli.core import AzCommandsLoader | ||
from azure.cli.core.profiles import register_resource_type | ||
import azext_keyvault_preview._help # pylint: disable=unused-import | ||
from .profiles import CUSTOM_MGMT_KEYVAULT | ||
|
||
|
||
class KeyVaultCommandsLoader(AzCommandsLoader): | ||
|
||
def __init__(self, cli_ctx=None): | ||
from azure.cli.core.commands import CliCommandType | ||
from ._client_factory import keyvault_mgmt_client_factory | ||
from azure.cli.command_modules.keyvault._command_type import KeyVaultCommandGroup, KeyVaultArgumentContext | ||
|
||
register_resource_type('latest', CUSTOM_MGMT_KEYVAULT, '2021-12-01-preview') | ||
|
||
keyvault_custom = CliCommandType( | ||
operations_tmpl='azext_keyvault_preview.custom#{}', | ||
client_factory=keyvault_mgmt_client_factory | ||
) | ||
|
||
super(KeyVaultCommandsLoader, self).__init__( | ||
cli_ctx=cli_ctx, | ||
resource_type=CUSTOM_MGMT_KEYVAULT, | ||
custom_command_type=keyvault_custom, | ||
command_group_cls=KeyVaultCommandGroup, | ||
argument_context_cls=KeyVaultArgumentContext) | ||
|
||
def load_command_table(self, args): | ||
from .commands import load_command_table | ||
load_command_table(self, args) | ||
return self.command_table | ||
|
||
def load_arguments(self, command): | ||
from ._params import load_arguments | ||
load_arguments(self, command) | ||
|
||
|
||
COMMAND_LOADER_CLS = KeyVaultCommandsLoader |
31 changes: 31 additions & 0 deletions
31
src/keyvault-preview/azext_keyvault_preview/_client_factory.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
from knack.util import CLIError | ||
from .profiles import CUSTOM_MGMT_KEYVAULT | ||
|
||
|
||
def keyvault_mgmt_client_factory(cli_ctx, **_): | ||
from azure.cli.core.commands.client_factory import get_mgmt_service_client | ||
return get_mgmt_service_client(cli_ctx, CUSTOM_MGMT_KEYVAULT) | ||
|
||
|
||
def cf_mhsm(cli_ctx, _): | ||
return keyvault_mgmt_client_factory(cli_ctx).managed_hsms | ||
|
||
|
||
def cf_mhsm_region(cli_ctx, _): | ||
return keyvault_mgmt_client_factory(cli_ctx).mhsm_regions | ||
|
||
|
||
def is_azure_stack_profile(cmd=None, cli_ctx=None): | ||
cli_ctx = cmd.cli_ctx if cmd else cli_ctx | ||
if not cli_ctx: | ||
raise CLIError("Can't judge profile without cli_ctx!") | ||
return cli_ctx.cloud.profile in [ | ||
'2020-09-01-hybrid', | ||
'2019-03-01-hybrid', | ||
'2018-03-01-hybrid', | ||
'2017-03-09-profile' | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.help_files import helps # pylint: disable=unused-import | ||
# pylint: disable=line-too-long, too-many-lines | ||
|
||
helps['keyvault region'] = """ | ||
type: group | ||
short-summary: Manage MHSM multi-regions. | ||
""" | ||
|
||
helps['keyvault region list'] = """ | ||
type: command | ||
short-summary: Get regions information associated with the managed HSM Pool. | ||
""" | ||
|
||
helps['keyvault region add'] = """ | ||
type: command | ||
short-summary: Add regions for the managed HSM Pool. | ||
examples: | ||
- name: Add regions for the managed HSM. | ||
text: | | ||
az keyvault region add --region-name westus2 --hsm-name myhsm --resource-group myrg | ||
""" | ||
|
||
helps['keyvault region remove'] = """ | ||
type: command | ||
short-summary: Remove regions for the managed HSM Pool. | ||
examples: | ||
- name: Remove regions for the managed HSM. | ||
text: | | ||
az keyvault region remove --region-name westus2 --hsm-name myhsm --resource-group myrg | ||
""" | ||
|
||
helps['keyvault region wait'] = """ | ||
type: command | ||
short-summary: Place the CLI in a waiting state until a condition of the HSM is met. | ||
examples: | ||
- name: Pause CLI until the regions are updated. | ||
text: | | ||
az keyvault region wait --hsm-name myhsm --updated | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
from knack.arguments import CLIArgumentType | ||
from azure.cli.core.commands.parameters import get_enum_type, resource_group_name_type, get_three_state_flag | ||
from ._validators import validate_resource_group_name | ||
from .profiles import CUSTOM_MGMT_KEYVAULT | ||
|
||
|
||
def load_arguments(self, _): | ||
NetworkRuleBypassOptions, NetworkRuleAction = self.get_models( | ||
'NetworkRuleBypassOptions', 'NetworkRuleAction', | ||
resource_type=CUSTOM_MGMT_KEYVAULT) | ||
|
||
hsm_name_type = CLIArgumentType(help='Name of the HSM.', | ||
options_list=['--hsm-name'], id_part=None) | ||
|
||
with self.argument_context('keyvault') as c: | ||
c.argument('name', hsm_name_type) | ||
c.argument('resource_group_name', resource_group_name_type, id_part=None, required=False, | ||
help='Proceed only if Key Vault belongs to the specified resource group.', | ||
validator=validate_resource_group_name) | ||
|
||
with self.argument_context('keyvault', arg_group='Network Rule', min_api='2018-02-14') as c: | ||
c.argument('bypass', arg_type=get_enum_type(NetworkRuleBypassOptions), | ||
help='Bypass traffic for space-separated uses.') | ||
c.argument('default_action', arg_type=get_enum_type(NetworkRuleAction), | ||
help='Default action to apply when no rule matches.') | ||
|
||
with self.argument_context('keyvault update-hsm') as c: | ||
c.argument('enable_purge_protection', options_list=['--enable-purge-protection', '-e'], | ||
arg_type=get_three_state_flag(), | ||
help='Property specifying whether protection against purge is enabled for this managed HSM pool. ' | ||
'Setting this property to true activates protection against purge for this managed HSM pool ' | ||
'and its content - only the Managed HSM service may initiate a hard, irrecoverable deletion. ' | ||
'The setting is effective only if soft delete is also enabled. ' | ||
'Enabling this functionality is irreversible.') | ||
|
||
with self.argument_context('keyvault region') as c: | ||
c.argument('region_name', options_list=['--region-name', '--region', '-r'], | ||
help='The region name.') |
40 changes: 40 additions & 0 deletions
40
src/keyvault-preview/azext_keyvault_preview/_validators.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
from knack.util import CLIError | ||
from azure.cli.command_modules.keyvault._validators import ( | ||
_show_vault_only_deprecate_message, _get_resource_group_from_resource_name | ||
) | ||
|
||
|
||
def validate_resource_group_name(cmd, ns): | ||
""" | ||
Populate resource_group_name, if not provided | ||
""" | ||
if 'keyvault purge' in cmd.name or 'keyvault recover' in cmd.name: | ||
return | ||
|
||
vault_name = getattr(ns, 'vault_name', None) | ||
hsm_name = getattr(ns, 'hsm_name', None) | ||
if 'keyvault update-hsm' in cmd.name or 'keyvault region': | ||
hsm_name = getattr(ns, 'name', None) | ||
|
||
if vault_name and hsm_name: | ||
raise CLIError('--name/-n and --hsm-name are mutually exclusive.') | ||
|
||
if vault_name: | ||
# This is a temporary solution for showing deprecation message only for vaults | ||
_show_vault_only_deprecate_message(ns) | ||
|
||
if not ns.resource_group_name: | ||
group_name = _get_resource_group_from_resource_name(cmd.cli_ctx, vault_name, hsm_name) | ||
if group_name: | ||
ns.resource_group_name = group_name | ||
else: | ||
if vault_name: | ||
resource_type = 'Vault' | ||
else: | ||
resource_type = 'HSM' | ||
msg = "The {} '{}' not found within subscription." | ||
raise CLIError(msg.format(resource_type, vault_name if vault_name else hsm_name)) |
3 changes: 3 additions & 0 deletions
3
src/keyvault-preview/azext_keyvault_preview/azext_metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"azext.isPreview": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
from azure.cli.core.commands import CliCommandType | ||
from ._client_factory import is_azure_stack_profile, cf_mhsm, cf_mhsm_region | ||
from .profiles import CUSTOM_MGMT_KEYVAULT | ||
|
||
|
||
def load_command_table(self, _): | ||
managed_hsm_sdk = CliCommandType( | ||
operations_tmpl='azext_keyvault_preview.vendored_sdks.azure_mgmt_keyvault.operations#' | ||
'ManagedHsmsOperations.{}', | ||
client_factory=cf_mhsm, | ||
resource_type=CUSTOM_MGMT_KEYVAULT | ||
) | ||
managed_hsm_custom = CliCommandType( | ||
operations_tmpl='azext_keyvault_preview.custom#{}', | ||
client_factory=cf_mhsm, | ||
resource_type=CUSTOM_MGMT_KEYVAULT | ||
) | ||
mhsm_region_sdk = CliCommandType( | ||
operations_tmpl='azext_keyvault_preview.vendored_sdks.azure_mgmt_keyvault.operations#' | ||
'MHSMRegionsOperations.{}', | ||
client_factory=cf_mhsm, | ||
resource_type=CUSTOM_MGMT_KEYVAULT | ||
) | ||
|
||
with self.command_group('keyvault', managed_hsm_sdk, min_api='2021-12-01-preview') as g: | ||
g.generic_update_command('update-hsm', custom_func_name='update_hsm', supports_no_wait=True, | ||
setter_name='update_hsm_setter', setter_type=managed_hsm_custom) | ||
|
||
with self.command_group('keyvault region', mhsm_region_sdk, client_factory=cf_mhsm_region, | ||
min_api='2021-12-01-preview', is_preview=True) as g: | ||
g.command('list', 'list_by_resource', client_factory=cf_mhsm_region) | ||
|
||
with self.command_group('keyvault region', managed_hsm_sdk, client_factory=cf_mhsm, | ||
min_api='2021-12-01-preview', is_preview=True) as g: | ||
g.custom_command('add', 'add_hsm_region', supports_no_wait=True) | ||
g.custom_command('remove', 'remove_hsm_region', supports_no_wait=True) | ||
g.wait_command('wait') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
from knack.log import get_logger | ||
from azure.cli.core.util import sdk_no_wait | ||
from .profiles import CUSTOM_MGMT_KEYVAULT | ||
|
||
logger = get_logger(__name__) | ||
|
||
|
||
def update_hsm_setter(cmd, client, parameters, resource_group_name, name, no_wait=False): | ||
ManagedHsm = cmd.get_models('ManagedHsm', resource_type=CUSTOM_MGMT_KEYVAULT) | ||
return sdk_no_wait(no_wait, client.begin_create_or_update, | ||
resource_group_name=resource_group_name, | ||
name=name, | ||
parameters=ManagedHsm( | ||
sku=parameters.sku, | ||
tags=parameters.tags, | ||
location=parameters.location, | ||
properties=parameters.properties)) | ||
|
||
|
||
def update_hsm(cmd, instance, | ||
enable_purge_protection=None, | ||
bypass=None, | ||
default_action=None): | ||
if enable_purge_protection is not None: | ||
instance.properties.enable_purge_protection = enable_purge_protection | ||
|
||
if bypass or default_action and (hasattr(instance.properties, 'network_acls')): | ||
if instance.properties.network_acls is None: | ||
instance.properties.network_acls = _create_network_rule_set(cmd, bypass, default_action) | ||
else: | ||
if bypass: | ||
instance.properties.network_acls.bypass = bypass | ||
if default_action: | ||
instance.properties.network_acls.default_action = default_action | ||
return instance | ||
|
||
|
||
def _create_network_rule_set(cmd, bypass=None, default_action=None): | ||
NetworkRuleSet = cmd.get_models('NetworkRuleSet', resource_type=CUSTOM_MGMT_KEYVAULT) | ||
NetworkRuleBypassOptions = cmd.get_models('NetworkRuleBypassOptions', resource_type=CUSTOM_MGMT_KEYVAULT) | ||
NetworkRuleAction = cmd.get_models('NetworkRuleAction', resource_type=CUSTOM_MGMT_KEYVAULT) | ||
|
||
return NetworkRuleSet(bypass=bypass or NetworkRuleBypassOptions.azure_services.value, | ||
default_action=default_action or NetworkRuleAction.allow.value) | ||
|
||
|
||
def add_hsm_region(cmd, client, resource_group_name, name, region_name, no_wait=False): | ||
MHSMGeoReplicatedRegion = cmd.get_models('MHSMGeoReplicatedRegion', resource_type=CUSTOM_MGMT_KEYVAULT) | ||
|
||
hsm = client.get(resource_group_name=resource_group_name, name=name) | ||
existing_regions = hsm.properties.regions or [] | ||
for existing_region in existing_regions: | ||
if region_name == existing_region.name: | ||
logger.warning("{} has already existed".format(region_name)) | ||
return hsm | ||
existing_regions.append(MHSMGeoReplicatedRegion(name=region_name)) | ||
hsm.properties.regions = existing_regions | ||
return sdk_no_wait(no_wait, client.begin_update, | ||
resource_group_name=resource_group_name, | ||
name=name, | ||
parameters=hsm) | ||
|
||
|
||
def remove_hsm_region(client, resource_group_name, name, region_name, no_wait=False): | ||
hsm = client.get(resource_group_name=resource_group_name, name=name) | ||
existing_regions = hsm.properties.regions or [] | ||
for existing_region in existing_regions: | ||
if region_name == existing_region.name: | ||
existing_regions.remove(existing_region) | ||
hsm.properties.regions = existing_regions | ||
return sdk_no_wait(no_wait, client.begin_update, | ||
resource_group_name=resource_group_name, | ||
name=name, parameters=hsm) | ||
logger.warning("{} doesn't exist".format(region_name)) | ||
return hsm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azure.cli.core.profiles import CustomResourceType | ||
|
||
CUSTOM_MGMT_KEYVAULT = CustomResourceType('azext_keyvault_preview.vendored_sdks.azure_mgmt_keyvault', | ||
'KeyVaultManagementClient') |
Oops, something went wrong.