Skip to content

Commit c6b39e7

Browse files
authored
[AKS] az aks update: Set CMK property "enabled" to false and remove other CMK properties when enable PMK on a CMK-disabled cluster (#9385)
1 parent b97d176 commit c6b39e7

File tree

5 files changed

+192
-3
lines changed

5 files changed

+192
-3
lines changed

src/aks-preview/HISTORY.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ To release a new version, please select a new version number (usually plus 1 to
1111

1212
Pending
1313
+++++++
14+
15+
19.0.0b11
16+
+++++++
1417
* Remove PMK validation for `--azure-keyvault-kms-key-id` parameter.
18+
* `az aks update`: Set CMK property "enabled" to false and remove other CMK properties when enabling PMK on a CMK-disabled cluster
1519

1620
19.0.0b10
1721
+++++++
@@ -34,7 +38,7 @@ Pending
3438
* `az aks create`: Add new parameter `--enable-container-network-logs` to enable container network logs feature for the cluster and deprecate `--enable-retina-flow-logs`.
3539
* `az aks update`: Add new parameter `--enable-container-network-logs` and `--disable-container-network-logs` to enable/disable container network logs feature for the cluster and deprecate `--enable-retina-flow-logs` and `--disable-retina-flow-logs`.
3640
* Support `entraid` for parameter `--ssh-access` to support EntraID feature.
37-
* `az aks update`: Set CMK property "enabled" to false and remove other CMK properties when "--disable-azure-keyvault-kms" is specified
41+
* `az aks update`: Set CMK property "enabled" to false and remove other CMK properties when disabling CMK on a PMK-enabled cluster
3842

3943
19.0.0b6
4044
+++++++

src/aks-preview/azext_aks_preview/managed_cluster_decorator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6020,7 +6020,10 @@ def update_kms_pmk_cmk(self, mc: ManagedCluster) -> ManagedCluster:
60206020
key_vault_resource_id=self.context.get_azure_keyvault_kms_key_vault_resource_id(),
60216021
)
60226022

6023-
if self.context.get_disable_azure_keyvault_kms():
6023+
cmk_disabled_on_existing_cluster = False
6024+
if mc.security_profile is not None and mc.security_profile.azure_key_vault_kms is not None and mc.security_profile.azure_key_vault_kms.enabled is False:
6025+
cmk_disabled_on_existing_cluster = True
6026+
if self.context.get_disable_azure_keyvault_kms() or cmk_disabled_on_existing_cluster:
60246027
if mc.security_profile is None:
60256028
mc.security_profile = self.models.ManagedClusterSecurityProfile()
60266029
mc.security_profile.azure_key_vault_kms = self.models.AzureKeyVaultKms()

src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12592,6 +12592,148 @@ def test_aks_create_with_kms_pmk_and_cmk_and_disable_cmk_private(
1259212592
],
1259312593
)
1259412594

12595+
@live_only()
12596+
@AllowLargeResponse()
12597+
@AKSCustomResourceGroupPreparer(
12598+
random_name_length=17,
12599+
name_prefix="clitest",
12600+
location="eastus2euap",
12601+
)
12602+
def test_aks_create_with_kms_cmk_and_disable_cmk_and_update_pmk(
12603+
self, resource_group, resource_group_location
12604+
):
12605+
"""Test creating CMK-enabled cluster, disabling CMK, then enabling PMK"""
12606+
aks_name = self.create_random_name("cliakstest", 16)
12607+
kv_name = self.create_random_name("cliakstestkv", 16)
12608+
identity_name = self.create_random_name("cliakstestidentity", 24)
12609+
k8s_version = self._get_version_in_range(location=resource_group_location, min_version="1.33.0", max_version="1.34.0")
12610+
self.kwargs.update(
12611+
{
12612+
"resource_group": resource_group,
12613+
"name": aks_name,
12614+
"kv_name": kv_name,
12615+
"identity_name": identity_name,
12616+
"ssh_key_value": self.generate_ssh_keys(),
12617+
"k8s_version": k8s_version,
12618+
}
12619+
)
12620+
12621+
# create user-assigned identity
12622+
identity_id = self._get_user_assigned_identity(resource_group)
12623+
identity_object_id = self._get_principal_id_of_user_assigned_identity(identity_id)
12624+
assert identity_id is not None
12625+
assert identity_object_id is not None
12626+
self.kwargs.update(
12627+
{
12628+
"identity_id": identity_id,
12629+
"identity_object_id": identity_object_id,
12630+
}
12631+
)
12632+
12633+
# create key vault and key first
12634+
create_keyvault = (
12635+
"keyvault create --resource-group={resource_group} --name={kv_name} --enable-rbac-authorization=false --no-self-perms -o json"
12636+
)
12637+
self.cmd(
12638+
create_keyvault,
12639+
checks=[self.check("properties.provisioningState", "Succeeded")],
12640+
)
12641+
12642+
# set access policy for test identity
12643+
test_identity_object_id = self._get_test_identity_object_id()
12644+
test_identity_access_policy = 'keyvault set-policy --resource-group={resource_group} --name={kv_name} ' \
12645+
'--key-permissions all --object-id ' + test_identity_object_id
12646+
self.cmd(test_identity_access_policy, checks=[
12647+
self.check('properties.provisioningState', 'Succeeded')
12648+
])
12649+
12650+
# create key and extract key IDs
12651+
create_key = "keyvault key create -n kms --vault-name {kv_name} -o json"
12652+
key = self.cmd(
12653+
create_key, checks=[self.check("attributes.enabled", True)]
12654+
).get_output_in_json()
12655+
key_id_versioned = key["key"]["kid"]
12656+
assert key_id_versioned is not None
12657+
self.kwargs.update(
12658+
{
12659+
"key_id_versioned": key_id_versioned,
12660+
}
12661+
)
12662+
12663+
# assign access policy for cluster identity
12664+
set_policy = (
12665+
"keyvault set-policy --resource-group={resource_group} --name={kv_name} "
12666+
"--object-id {identity_object_id} --key-permissions encrypt decrypt -o json"
12667+
)
12668+
self.cmd(
12669+
set_policy, checks=[self.check("properties.provisioningState", "Succeeded")]
12670+
)
12671+
12672+
# create cluster with CMK enabled (use versioned key ID for creation)
12673+
create_cmd = (
12674+
"aks create --resource-group={resource_group} --name={name} "
12675+
"--assign-identity {identity_id} "
12676+
"--enable-azure-keyvault-kms --azure-keyvault-kms-key-id={key_id_versioned} "
12677+
"--azure-keyvault-kms-key-vault-network-access=Public "
12678+
"--kubernetes-version={k8s_version} "
12679+
"--ssh-key-value={ssh_key_value} "
12680+
"-o json"
12681+
)
12682+
self.cmd(
12683+
create_cmd,
12684+
checks=[
12685+
self.check("provisioningState", "Succeeded"),
12686+
self.check("securityProfile.azureKeyVaultKms.enabled", True),
12687+
self.check("securityProfile.azureKeyVaultKms.keyId", key_id_versioned),
12688+
self.not_exists("securityProfile.kubernetesResourceObjectEncryptionProfile"),
12689+
],
12690+
)
12691+
12692+
# disable CMK
12693+
disable_cmk_cmd = (
12694+
"aks update --resource-group={resource_group} --name={name} "
12695+
"--disable-azure-keyvault-kms "
12696+
"-o json"
12697+
)
12698+
self.cmd(
12699+
disable_cmk_cmd,
12700+
checks=[
12701+
self.check("provisioningState", "Succeeded"),
12702+
self.check("securityProfile.azureKeyVaultKms.enabled", False),
12703+
self.not_exists("securityProfile.kubernetesResourceObjectEncryptionProfile"),
12704+
],
12705+
)
12706+
12707+
# enable PMK on cluster with disabled CMK
12708+
enable_pmk_cmd = (
12709+
"aks update --resource-group={resource_group} --name={name} "
12710+
"--kms-infrastructure-encryption Enabled "
12711+
"--aks-custom-headers AKSHTTPCustomFeatures=Microsoft.ContainerService/KMSPMKPreview "
12712+
"-o json"
12713+
)
12714+
self.cmd(
12715+
enable_pmk_cmd,
12716+
checks=[
12717+
self.check("provisioningState", "Succeeded"),
12718+
self.check("securityProfile.azureKeyVaultKms.enabled", False),
12719+
self.check(
12720+
"securityProfile.kubernetesResourceObjectEncryptionProfile.infrastructureEncryption",
12721+
"Enabled"
12722+
),
12723+
],
12724+
)
12725+
12726+
# delete
12727+
cmd = (
12728+
"aks delete --resource-group={resource_group} --name={name} --yes --no-wait"
12729+
)
12730+
self.cmd(
12731+
cmd,
12732+
checks=[
12733+
self.is_empty(),
12734+
],
12735+
)
12736+
1259512737
@AllowLargeResponse()
1259612738
@AKSCustomResourceGroupPreparer(
1259712739
random_name_length=17,

src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8839,6 +8839,46 @@ def test_update_kms_pmk_cmk(self):
88398839
)
88408840
self.assertEqual(dec_mc_10, ground_truth_mc_10)
88418841

8842+
# test enabling PMK on cluster with disabled CMK - should clear CMK properties
8843+
dec_11 = AKSPreviewManagedClusterUpdateDecorator(
8844+
self.cmd,
8845+
self.client,
8846+
{
8847+
"kms_infrastructure_encryption": "Enabled",
8848+
},
8849+
CUSTOM_MGMT_AKS_PREVIEW,
8850+
)
8851+
# Start with a cluster that has CMK disabled with existing properties
8852+
existing_security_profile = self.models.ManagedClusterSecurityProfile(
8853+
azure_key_vault_kms=self.models.AzureKeyVaultKms(
8854+
enabled=False,
8855+
key_id="https://test-keyvault.vault.azure.net/keys/test-key",
8856+
key_vault_resource_id="/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.KeyVault/vaults/test-keyvault",
8857+
)
8858+
)
8859+
mc_11 = self.models.ManagedCluster(
8860+
location="test_location",
8861+
security_profile=existing_security_profile,
8862+
)
8863+
dec_11.context.attach_mc(mc_11)
8864+
dec_mc_11 = dec_11.update_kms_pmk_cmk(mc_11)
8865+
8866+
# should clear CMK properties and enable PMK
8867+
ground_truth_azure_key_vault_kms_11 = self.models.AzureKeyVaultKms()
8868+
ground_truth_azure_key_vault_kms_11.enabled = False
8869+
ground_truth_kube_resource_encryption_profile_11 = self.models.KubernetesResourceObjectEncryptionProfile(
8870+
infrastructure_encryption="Enabled"
8871+
)
8872+
ground_truth_security_profile_11 = self.models.ManagedClusterSecurityProfile(
8873+
azure_key_vault_kms=ground_truth_azure_key_vault_kms_11,
8874+
kubernetes_resource_object_encryption_profile=ground_truth_kube_resource_encryption_profile_11,
8875+
)
8876+
ground_truth_mc_11 = self.models.ManagedCluster(
8877+
location="test_location",
8878+
security_profile=ground_truth_security_profile_11,
8879+
)
8880+
self.assertEqual(dec_mc_11, ground_truth_mc_11)
8881+
88428882
def test_update_workload_auto_scaler_profile(self):
88438883
# Throws exception when incorrect mc object is passed.
88448884
dec_1 = AKSPreviewManagedClusterUpdateDecorator(

src/aks-preview/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from setuptools import find_packages, setup
1111

12-
VERSION = "19.0.0b10"
12+
VERSION = "19.0.0b11"
1313

1414
CLASSIFIERS = [
1515
"Development Status :: 4 - Beta",

0 commit comments

Comments
 (0)