diff --git a/src/aks-preview/HISTORY.md b/src/aks-preview/HISTORY.md index c9e1958a05c..5cd5de8f051 100644 --- a/src/aks-preview/HISTORY.md +++ b/src/aks-preview/HISTORY.md @@ -6,6 +6,7 @@ Release History +++++ * Add --enable-azure-rbac and --disable-azure-rbac in aks update * Support disabling local accounts +* Add addon `azure-defender` to list of available addons under `az aks enable-addons` command 0.5.11 +++++ diff --git a/src/aks-preview/azext_aks_preview/_consts.py b/src/aks-preview/azext_aks_preview/_consts.py index 642e28fca36..6d759a00d03 100644 --- a/src/aks-preview/azext_aks_preview/_consts.py +++ b/src/aks-preview/azext_aks_preview/_consts.py @@ -64,7 +64,12 @@ CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME = "azureKeyvaultSecretsProvider" CONST_SECRET_ROTATION_ENABLED = "enableSecretRotation" +# Azure Defender addon configuration keys +CONST_AZURE_DEFENDER_ADDON_NAME = "azureDefender" +CONST_AZURE_DEFENDER_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID = CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID + ADDONS = { + 'azure-defender': CONST_AZURE_DEFENDER_ADDON_NAME, 'http_application_routing': CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME, 'monitoring': CONST_MONITORING_ADDON_NAME, 'virtual-node': CONST_VIRTUAL_NODE_ADDON_NAME, diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index 19d0df44076..3c62bd1763e 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -171,6 +171,7 @@ open-service-mesh - enable Open Service Mesh addon (PREVIEW). gitops - enable GitOps (PREVIEW). azure-keyvault-secrets-provider - enable Azure Keyvault Secrets Provider addon (PREVIEW). + azure-defender - enable Azure Defender addon (PREVIEW). - name: --disable-rbac type: bool short-summary: Disable Kubernetes Role-Based Access Control. @@ -1009,6 +1010,8 @@ open-service-mesh - enable Open Service Mesh addon (PREVIEW). gitops - enable GitOps (PREVIEW). azure-keyvault-secrets-provider - enable Azure Keyvault Secrets Provider addon (PREVIEW). + azure-defender - enable Azure Defender addon (PREVIEW). + parameters: - name: --addons -a type: string @@ -1053,6 +1056,9 @@ - name: Enable open-service-mesh addon. text: az aks enable-addons --name MyManagedCluster --resource-group MyResourceGroup --addons open-service-mesh crafted: true + - name: Enable azure-defender addon with workspace resourceId. + text: az aks enable-addons --name MyManagedCluster --resource-group MyResourceGroup --addons azure-defender --workspace-resource-id WorkspaceResourceId + crafted: true """ helps['aks get-versions'] = """ diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index 35d41490f43..0d13f548e0a 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -113,6 +113,7 @@ from ._consts import CONST_CONFCOM_ADDON_NAME, CONST_ACC_SGX_QUOTE_HELPER_ENABLED from ._consts import CONST_OPEN_SERVICE_MESH_ADDON_NAME from ._consts import CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, CONST_SECRET_ROTATION_ENABLED +from ._consts import CONST_AZURE_DEFENDER_ADDON_NAME, CONST_AZURE_DEFENDER_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID from ._consts import CONST_MANAGED_IDENTITY_OPERATOR_ROLE, CONST_MANAGED_IDENTITY_OPERATOR_ROLE_ID from ._consts import ADDONS from .maintenanceconfiguration import aks_maintenanceconfiguration_update_internal @@ -2377,24 +2378,24 @@ def _handle_addons_args(cmd, # pylint: disable=too-many-statements enabled=True) addons.remove('kube-dashboard') # TODO: can we help the user find a workspace resource ID? - if 'monitoring' in addons: + if 'monitoring' in addons or 'azure-defender' in addons: if not workspace_resource_id: # use default workspace if exists else create default workspace workspace_resource_id = _ensure_default_log_analytics_workspace_for_monitoring( cmd, subscription_id, resource_group_name) - workspace_resource_id = workspace_resource_id.strip() - if not workspace_resource_id.startswith('/'): - workspace_resource_id = '/' + workspace_resource_id - if workspace_resource_id.endswith('/'): - workspace_resource_id = workspace_resource_id.rstrip('/') - addon_profiles[CONST_MONITORING_ADDON_NAME] = ManagedClusterAddonProfile( - enabled=True, config={CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id}) - addons.remove('monitoring') - # error out if '--enable-addons=monitoring' isn't set but workspace_resource_id is + workspace_resource_id = _sanitize_loganalytics_ws_resource_id(workspace_resource_id) + + if 'monitoring' in addons: + addon_profiles[CONST_MONITORING_ADDON_NAME] = ManagedClusterAddonProfile(enabled=True, config={CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id}) + addons.remove('monitoring') + if 'azure-defender' in addons: + addon_profiles[CONST_AZURE_DEFENDER_ADDON_NAME] = ManagedClusterAddonProfile(enabled=True, config={CONST_AZURE_DEFENDER_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id}) + addons.remove('azure-defender') + # error out if '--enable-addons=monitoring/azure-defender' isn't set but workspace_resource_id is elif workspace_resource_id: raise CLIError( - '"--workspace-resource-id" requires "--enable-addons monitoring".') + '"--workspace-resource-id" requires "--enable-addons [monitoring/azure-defender]".') if 'azure-policy' in addons: addon_profiles[CONST_AZURE_POLICY_ADDON_NAME] = ManagedClusterAddonProfile( enabled=True) @@ -2631,6 +2632,15 @@ def _ensure_default_log_analytics_workspace_for_monitoring(cmd, subscription_id, return ws_resource_id +def _sanitize_loganalytics_ws_resource_id(workspace_resource_id): + workspace_resource_id = workspace_resource_id.strip() + if not workspace_resource_id.startswith('/'): + workspace_resource_id = '/' + workspace_resource_id + if workspace_resource_id.endswith('/'): + workspace_resource_id = workspace_resource_id.rstrip('/') + return workspace_resource_id + + def _ensure_container_insights_for_monitoring(cmd, addon): if not addon.enabled: return None @@ -3340,23 +3350,21 @@ def _update_addons(cmd, # pylint: disable=too-many-branches,too-many-statements addon_profile = addon_profiles.get( addon, ManagedClusterAddonProfile(enabled=False)) # special config handling for certain addons - if addon == CONST_MONITORING_ADDON_NAME: + if addon in [CONST_MONITORING_ADDON_NAME, CONST_AZURE_DEFENDER_ADDON_NAME]: + logAnalyticsConstName = CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID if addon == CONST_MONITORING_ADDON_NAME else CONST_AZURE_DEFENDER_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID if addon_profile.enabled: - raise CLIError('The monitoring addon is already enabled for this managed cluster.\n' - 'To change monitoring configuration, run "az aks disable-addons -a monitoring"' + raise CLIError(f'The {addon} addon is already enabled for this managed cluster.\n' + f'To change {addon} configuration, run "az aks disable-addons -a {addon}"' 'before enabling it again.') if not workspace_resource_id: workspace_resource_id = _ensure_default_log_analytics_workspace_for_monitoring( cmd, subscription_id, resource_group_name) - workspace_resource_id = workspace_resource_id.strip() - if not workspace_resource_id.startswith('/'): - workspace_resource_id = '/' + workspace_resource_id - if workspace_resource_id.endswith('/'): - workspace_resource_id = workspace_resource_id.rstrip('/') + workspace_resource_id = _sanitize_loganalytics_ws_resource_id(workspace_resource_id) + addon_profile.config = { - CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id} + logAnalyticsConstName: workspace_resource_id} elif addon == (CONST_VIRTUAL_NODE_ADDON_NAME + os_type): if addon_profile.enabled: raise CLIError('The virtual-node addon is already enabled for this managed cluster.\n'