-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[AKS] feat: Azure Monitor Metrics addon (v2) (Managed Prometheus) GA #26201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d9201fc
5038ec1
8cd010e
e76a69f
b70b17f
6db0710
4e049b1
49ba459
7debb4d
3b43a05
57f7eba
fb435ab
a41cb3a
1635170
efd8bb9
081ac83
5427e44
9091ef7
b71f454
411fe13
a860239
9f6d94f
505edf3
711f42a
d8e9811
4b360c6
9e8862d
4e40299
262759e
ffb96f0
a8b41f2
ce9c42e
774649e
963621a
f4a7f31
104af48
03d907a
31b0d91
d3efd9f
80f9d85
fb766a4
dea7db8
0b81ab6
5f6aeba
929f564
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
|
bragi92 marked this conversation as resolved.
|
||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
| import json | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.constants import AKS_CLUSTER_API | ||
| from azure.cli.core.azclierror import ( | ||
| UnknownError, | ||
| CLIError | ||
| ) | ||
|
|
||
|
|
||
| # pylint: disable=line-too-long | ||
| def addon_put(cmd, cluster_subscription, cluster_resource_group_name, cluster_name): | ||
| from azure.cli.core.util import send_raw_request | ||
| armendpoint = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
| feature_check_url = f"{armendpoint}/subscriptions/{cluster_subscription}/resourceGroups/{cluster_resource_group_name}/providers/Microsoft.ContainerService/managedClusters/{cluster_name}?api-version={AKS_CLUSTER_API}" | ||
| try: | ||
| headers = ['User-Agent=azuremonitormetrics.addon_get'] | ||
| r = send_raw_request(cmd.cli_ctx, "GET", feature_check_url, | ||
| body={}, headers=headers) | ||
|
Comment on lines
+17
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this REST request not currently supported in the Python SDK?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have done a bug bash using this version of the CLI within the team and everything looks good with it and hence I would like to release this version of the azure monitor metrics addon in the build CLI otherwise we will have to do a bug bash for the whole team again as the REST api code is critical to the addon enablement. I think your feedback is valid so I have created a follow up task here. Can I create a follow up PR for this and merge it in after the May 17th code complete cut-off for build so that this version which has been tested by everyone in our team can go out?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, sounds good. Perhaps another good option is to try using Code Gen V2 to generate these new commands, which can improve your development efficiency and ensure code standardization and quality. If you are interested in it, you can contact @kairu-ms |
||
| except CLIError as e: | ||
| raise UnknownError(e) | ||
| json_response = json.loads(r.text) | ||
| if "azureMonitorProfile" in json_response["properties"]: | ||
| if "metrics" in json_response["properties"]["azureMonitorProfile"]: | ||
| if json_response["properties"]["azureMonitorProfile"]["metrics"]["enabled"] is False: | ||
| # What if enabled doesn't exist | ||
| json_response["properties"]["azureMonitorProfile"]["metrics"]["enabled"] = True | ||
| try: | ||
| headers = ['User-Agent=azuremonitormetrics.addon_put'] | ||
| body = json.dumps(json_response) | ||
| r = send_raw_request(cmd.cli_ctx, "PUT", feature_check_url, | ||
| body=body, headers=headers) | ||
| except CLIError as e: | ||
| raise UnknownError(e) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
| import json | ||
| import uuid | ||
| from knack.util import CLIError | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.constants import ( | ||
| GRAFANA_API, | ||
| GRAFANA_ROLE_ASSIGNMENT_API, | ||
| GrafanaLink | ||
| ) | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.helper import sanitize_resource_id | ||
|
|
||
|
|
||
| def link_grafana_instance(cmd, raw_parameters, azure_monitor_workspace_resource_id): | ||
| from azure.cli.core.util import send_raw_request | ||
| # GET grafana principal ID | ||
| try: | ||
| grafana_resource_id = raw_parameters.get("grafana_resource_id") | ||
| if grafana_resource_id is None or grafana_resource_id == "": | ||
| return GrafanaLink.NOPARAMPROVIDED | ||
| grafana_resource_id = sanitize_resource_id(grafana_resource_id) | ||
| grafanaURI = "{0}{1}?api-version={2}".format( | ||
| cmd.cli_ctx.cloud.endpoints.resource_manager, | ||
| grafana_resource_id, | ||
| GRAFANA_API | ||
| ) | ||
| headers = ['User-Agent=azuremonitormetrics.link_grafana_instance'] | ||
| grafanaArmResponse = send_raw_request(cmd.cli_ctx, "GET", grafanaURI, body={}, headers=headers) | ||
| servicePrincipalId = grafanaArmResponse.json()["identity"]["principalId"] | ||
| except CLIError as e: | ||
| raise CLIError(e) | ||
| # Add Role Assignment | ||
| try: | ||
| MonitoringDataReader = "b0d8363b-8ddd-447d-831f-62ca05bff136" | ||
| roleDefinitionURI = "{0}{1}/providers/Microsoft.Authorization/roleAssignments/{2}?api-version={3}".format( | ||
| cmd.cli_ctx.cloud.endpoints.resource_manager, | ||
| azure_monitor_workspace_resource_id, | ||
| uuid.uuid4(), | ||
| GRAFANA_ROLE_ASSIGNMENT_API | ||
| ) | ||
| roleDefinitionId = "{0}/providers/Microsoft.Authorization/roleDefinitions/{1}".format( | ||
| azure_monitor_workspace_resource_id, | ||
| MonitoringDataReader | ||
| ) | ||
| association_body = json.dumps({ | ||
| "properties": { | ||
| "roleDefinitionId": roleDefinitionId, | ||
| "principalId": servicePrincipalId | ||
| } | ||
| }) | ||
| headers = ['User-Agent=azuremonitormetrics.add_role_assignment'] | ||
| send_raw_request(cmd.cli_ctx, "PUT", roleDefinitionURI, body=association_body, headers=headers) | ||
| except CLIError as e: | ||
| if e.response.status_code != 409: | ||
| erroString = "Role Assingment failed. Please manually assign the `Monitoring Data Reader` role\ | ||
| to the Azure Monitor Workspace ({0}) for the Azure Managed Grafana\ | ||
| System Assigned Managed Identity ({1})".format( | ||
| azure_monitor_workspace_resource_id, | ||
| servicePrincipalId | ||
| ) | ||
| print(erroString) | ||
| # Setting up AMW Integration | ||
| targetGrafanaArmPayload = grafanaArmResponse.json() | ||
| if targetGrafanaArmPayload["properties"] is None: | ||
| raise CLIError("Invalid grafana payload to add AMW integration") | ||
| if "grafanaIntegrations" not in json.dumps(targetGrafanaArmPayload): | ||
| targetGrafanaArmPayload["properties"]["grafanaIntegrations"] = {} | ||
| if "azureMonitorWorkspaceIntegrations" not in json.dumps(targetGrafanaArmPayload): | ||
| targetGrafanaArmPayload["properties"]["grafanaIntegrations"]["azureMonitorWorkspaceIntegrations"] = [] | ||
| amwIntegrations = targetGrafanaArmPayload["properties"]["grafanaIntegrations"]["azureMonitorWorkspaceIntegrations"] | ||
| if amwIntegrations != [] and azure_monitor_workspace_resource_id in json.dumps(amwIntegrations).lower(): | ||
| return GrafanaLink.ALREADYPRESENT | ||
| try: | ||
| grafanaURI = "{0}{1}?api-version={2}".format( | ||
| cmd.cli_ctx.cloud.endpoints.resource_manager, | ||
| grafana_resource_id, | ||
| GRAFANA_API | ||
| ) | ||
| targetGrafanaArmPayload["properties"]["grafanaIntegrations"]["azureMonitorWorkspaceIntegrations"].append({ | ||
| "azureMonitorWorkspaceResourceId": azure_monitor_workspace_resource_id | ||
| }) | ||
| targetGrafanaArmPayload = json.dumps(targetGrafanaArmPayload) | ||
| headers = ['User-Agent=azuremonitormetrics.setup_amw_grafana_integration', 'Content-Type=application/json'] | ||
| send_raw_request(cmd.cli_ctx, "PUT", grafanaURI, body=targetGrafanaArmPayload, headers=headers) | ||
| except CLIError as e: | ||
| raise CLIError(e) | ||
| return GrafanaLink.SUCCESS |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
| import json | ||
|
|
||
| from azure.cli.command_modules.acs.azuremonitormetrics.constants import MAC_API | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.amw.defaults import get_default_mac_name_and_region | ||
| from azure.cli.command_modules.acs._client_factory import get_resource_groups_client, get_resources_client | ||
| from azure.core.exceptions import HttpResponseError | ||
| from knack.util import CLIError | ||
|
|
||
|
|
||
| def create_default_mac(cmd, cluster_subscription, cluster_region): | ||
| from azure.cli.core.util import send_raw_request | ||
| default_mac_name, default_mac_region = get_default_mac_name_and_region(cmd, cluster_region) | ||
| default_resource_group_name = "DefaultResourceGroup-{0}".format(default_mac_region) | ||
| azure_monitor_workspace_resource_id = \ | ||
| "/subscriptions/{0}/resourceGroups/{1}/providers/microsoft.monitor/accounts/{2}"\ | ||
| .format( | ||
| cluster_subscription, | ||
| default_resource_group_name, | ||
| default_mac_name | ||
| ) | ||
| # Check if default resource group exists or not, if it does not then create it | ||
| resource_groups = get_resource_groups_client(cmd.cli_ctx, cluster_subscription) | ||
| resources = get_resources_client(cmd.cli_ctx, cluster_subscription) | ||
|
|
||
| if resource_groups.check_existence(default_resource_group_name): | ||
| try: | ||
| resource = resources.get_by_id(azure_monitor_workspace_resource_id, MAC_API) | ||
| # If MAC already exists then return from here | ||
| return azure_monitor_workspace_resource_id, resource.location | ||
| except HttpResponseError as ex: | ||
| if ex.status_code != 404: | ||
| raise ex | ||
| else: | ||
| resource_groups.create_or_update(default_resource_group_name, {"location": default_mac_region}) | ||
| association_body = json.dumps({"location": default_mac_region, "properties": {}}) | ||
| armendpoint = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
| association_url = f"{armendpoint}{azure_monitor_workspace_resource_id}?api-version={MAC_API}" | ||
| try: | ||
| headers = ['User-Agent=azuremonitormetrics.create_default_mac'] | ||
| send_raw_request(cmd.cli_ctx, "PUT", association_url, | ||
| body=association_body, headers=headers) | ||
| return azure_monitor_workspace_resource_id, default_mac_region | ||
| except CLIError as e: | ||
| raise e |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # -------------------------------------------------------------------------------------------- | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
| # -------------------------------------------------------------------------------------------- | ||
| import json | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.deaults import get_default_region | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.responseparsers.amwlocationresponseparser import ( | ||
| parseResourceProviderResponseForLocations | ||
| ) | ||
| from azure.cli.command_modules.acs.azuremonitormetrics.constants import RP_LOCATION_API | ||
| from knack.util import CLIError | ||
|
|
||
|
|
||
| def get_supported_rp_locations(cmd, rp_name): | ||
| from azure.cli.core.util import send_raw_request | ||
| supported_locations = [] | ||
| headers = ['User-Agent=azuremonitormetrics.get_supported_rp_locations'] | ||
| armendpoint = cmd.cli_ctx.cloud.endpoints.resource_manager | ||
| association_url = f"{armendpoint}/providers/{rp_name}?api-version={RP_LOCATION_API}" | ||
| r = send_raw_request(cmd.cli_ctx, "GET", association_url, headers=headers) | ||
| data = json.loads(r.text) | ||
| supported_locations = parseResourceProviderResponseForLocations(data) | ||
| return supported_locations | ||
|
|
||
|
|
||
| def get_default_mac_region(cmd, cluster_region): | ||
| supported_locations = get_supported_rp_locations(cmd, 'Microsoft.Monitor') | ||
| if cluster_region in supported_locations: | ||
| return cluster_region | ||
| if len(supported_locations) > 0: | ||
| return supported_locations[0] | ||
| cloud_name = cmd.cli_ctx.cloud.name | ||
| if cloud_name.lower() == 'azurechinacloud': | ||
| raise CLIError("Azure China Cloud is not supported for the Azure Monitor Metrics addon") | ||
| if cloud_name.lower() == 'azureusgovernment': | ||
| return "usgovvirginia" | ||
| # default to public cloud | ||
| return get_default_region(cmd) | ||
|
|
||
|
|
||
| def get_default_mac_name_and_region(cmd, cluster_region): | ||
| default_mac_region = get_default_mac_region(cmd, cluster_region) | ||
| default_mac_name = "DefaultAzureMonitorWorkspace-" + default_mac_region | ||
| default_mac_name = default_mac_name[0:43] | ||
| return default_mac_name, default_mac_region |
Uh oh!
There was an error while loading. Please reload this page.