diff --git a/src/azure-cli/azure/cli/command_modules/monitor/_client_factory.py b/src/azure-cli/azure/cli/command_modules/monitor/_client_factory.py index 3f61f9f0f30..a05ac9321d4 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/_client_factory.py @@ -55,6 +55,10 @@ def cf_metric_def(cli_ctx, _): return cf_monitor(cli_ctx).metric_definitions +def cf_metric_ns(cli_ctx, _): + return cf_monitor(cli_ctx).metric_namespaces + + def cf_activity_log(cli_ctx, _): return cf_monitor(cli_ctx).activity_logs diff --git a/src/azure-cli/azure/cli/command_modules/monitor/_help.py b/src/azure-cli/azure/cli/command_modules/monitor/_help.py index ab6b4c85ab4..909998ae52f 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/_help.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/_help.py @@ -1645,7 +1645,7 @@ - name: --namespace short-summary: Namespace to query metric definitions for. populator-commands: - - az monitor metrics list-definitions + - az monitor metrics list-namespaces - name: --offset short-summary: > Time offset of the query range, in ##d##h format. @@ -1694,14 +1694,28 @@ helps['monitor metrics list-definitions'] = """ type: command -short-summary: Lists the metric definitions for the resource. +short-summary: List the metric definitions for the resource. +parameters: + - name: --namespace + short-summary: Namespace to query metric definitions for. + populator-commands: + - az monitor metrics list-namespaces examples: - - name: Lists the metric definitions for the resource. (autogenerated) + - name: List the metric definitions for the resource. (autogenerated) text: | - az monitor metrics list-definitions --resource /subscriptions/{subscriptionID}/resourceGroups/Space1999/providers/Microsoft.Network/networkSecurityGroups/ADDS-NSG + az monitor metrics list-definitions --resource /subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/Microsoft.Network/networkSecurityGroups/{resourceName} crafted: true """ +helps['monitor metrics list-namespaces'] = """ +type: command +short-summary: List the metric namespaces for the resource. +examples: + - name: List the metric namespaces for the resource. + text: | + az monitor metrics list-namespaces --resource /subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/Microsoft.Network/networkSecurityGroups/{resourceName} --start-time 2021-03-01T00:00:00Z +""" + helps['monitor clone'] = """ type: command short-summary: Clone metrics alert rules from one resource to another resource. diff --git a/src/azure-cli/azure/cli/command_modules/monitor/_params.py b/src/azure-cli/azure/cli/command_modules/monitor/_params.py index be1e3fd1dbc..940517b35c9 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/_params.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/_params.py @@ -110,6 +110,9 @@ def load_arguments(self, _): c.argument('end_time', arg_type=get_datetime_type(help='End time of the query. Defaults to the current time.')) c.argument('offset', type=get_period_type(as_timedelta=True)) c.argument('interval', arg_group='Time', type=get_period_type()) + + with self.argument_context('monitor metrics list-namespaces', arg_group='Time') as c: + c.argument('start_time', arg_type=get_datetime_type(help='Start time of the query.')) # endregion # region MetricAlerts diff --git a/src/azure-cli/azure/cli/command_modules/monitor/commands.py b/src/azure-cli/azure/cli/command_modules/monitor/commands.py index bc370abc403..2abf8e5f1fa 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/commands.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/commands.py @@ -11,7 +11,7 @@ def load_command_table(self, _): from ._client_factory import ( cf_alert_rules, cf_metric_def, cf_alert_rule_incidents, cf_log_profiles, cf_autoscale, cf_diagnostics, cf_activity_log, cf_action_groups, cf_activity_log_alerts, cf_event_categories, - cf_metric_alerts, cf_log_analytics_deleted_workspaces, cf_log_analytics_workspace, + cf_metric_alerts, cf_metric_ns, cf_log_analytics_deleted_workspaces, cf_log_analytics_workspace, cf_log_analytics_workspace_tables, cf_log_analytics_workspace_management_groups, cf_log_analytics_workspace_usage, cf_log_analytics_workspace_schema, cf_log_analytics_workspace_shared_keys, cf_log_analytics_workspace_intelligence_packs, cf_log_analytics_cluster, @@ -144,6 +144,13 @@ def load_command_table(self, _): operation_group='metric_definitions', exception_handler=exception_handler) + metric_namespaces_sdk = CliCommandType( + operations_tmpl='azure.mgmt.monitor.operations#MetricNamespacesOperations.{}', + client_factory=cf_metric_ns, + operation_group='metric_namespaces', + exception_handler=exception_handler + ) + log_analytics_workspace_sdk = CliCommandType( operations_tmpl='azure.mgmt.loganalytics.operations#WorkspacesOperations.{}', client_factory=cf_log_analytics_workspace, @@ -345,9 +352,10 @@ def load_command_table(self, _): g.generic_update_command('update') with self.command_group('monitor metrics') as g: - from .transformers import metrics_table, metrics_definitions_table + from .transformers import metrics_table, metrics_definitions_table, metrics_namespaces_table g.command('list', 'list_metrics', command_type=monitor_custom, table_transformer=metrics_table) g.command('list-definitions', 'list', command_type=metric_definitions_sdk, table_transformer=metrics_definitions_table) + g.command('list-namespaces', 'list', is_preview=True, command_type=metric_namespaces_sdk, table_transformer=metrics_namespaces_table) with self.command_group('monitor metrics alert', metric_alert_sdk, custom_command_type=alert_custom, client_factory=cf_metric_alerts) as g: g.custom_command('create', 'create_metric_alert') diff --git a/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/recordings/test_monitor_metrics_scenario.yaml b/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/recordings/test_monitor_metrics_scenario.yaml index 91d9702076e..cd2bd6e785f 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/recordings/test_monitor_metrics_scenario.yaml +++ b/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/recordings/test_monitor_metrics_scenario.yaml @@ -13,12 +13,12 @@ interactions: ParameterSetName: - -n -g User-Agent: - - AZURECLI/2.19.1 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-storage/17.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002?api-version=2021-01-01 response: body: - string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","name":"clitest000002","type":"Microsoft.Storage/storageAccounts","location":"westus","tags":{},"properties":{"privateEndpointConnections":[],"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-02-22T11:26:09.6807544Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-02-22T11:26:09.6807544Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-02-22T11:26:09.5870159Z","primaryEndpoints":{"blob":"https://clitest000002.blob.core.windows.net/","queue":"https://clitest000002.queue.core.windows.net/","table":"https://clitest000002.table.core.windows.net/","file":"https://clitest000002.file.core.windows.net/"},"primaryLocation":"westus","statusOfPrimary":"available"}}' + string: '{"sku":{"name":"Standard_LRS","tier":"Standard"},"kind":"Storage","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002","name":"clitest000002","type":"Microsoft.Storage/storageAccounts","location":"westus","tags":{},"properties":{"privateEndpointConnections":[],"networkAcls":{"bypass":"AzureServices","virtualNetworkRules":[],"ipRules":[],"defaultAction":"Allow"},"supportsHttpsTrafficOnly":true,"encryption":{"services":{"file":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-26T06:43:57.1346253Z"},"blob":{"keyType":"Account","enabled":true,"lastEnabledTime":"2021-03-26T06:43:57.1346253Z"}},"keySource":"Microsoft.Storage"},"provisioningState":"Succeeded","creationTime":"2021-03-26T06:43:57.0565196Z","primaryEndpoints":{"blob":"https://clitest000002.blob.core.windows.net/","queue":"https://clitest000002.queue.core.windows.net/","table":"https://clitest000002.table.core.windows.net/","file":"https://clitest000002.file.core.windows.net/"},"primaryLocation":"westus","statusOfPrimary":"available"}}' headers: cache-control: - no-cache @@ -27,7 +27,7 @@ interactions: content-type: - application/json date: - - Mon, 22 Feb 2021 11:26:30 GMT + - Fri, 26 Mar 2021 06:44:16 GMT expires: - '-1' pragma: @@ -45,6 +45,54 @@ interactions: status: code: 200 message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + CommandName: + - monitor metrics list-namespaces + Connection: + - keep-alive + ParameterSetName: + - --resource + User-Agent: + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) + method: GET + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricNamespaces?api-version=2017-12-01-preview + response: + body: + string: '{"value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricNamespaces/Microsoft.Storage-storageAccounts","name":"Microsoft.Storage-storageAccounts","type":"Microsoft.Insights/metricNamespaces","classification":"Platform","properties":{"metricNamespaceName":"Microsoft.Storage/storageAccounts"}}]}' + headers: + access-control-expose-headers: + - Request-Context + cache-control: + - no-cache + content-length: + - '501' + content-type: + - application/json + date: + - Fri, 26 Mar 2021 06:44:17 GMT + request-context: + - appId=cid-v1:b021da79-5252-4375-9df5-2e17c1dcd822 + server: + - Microsoft-IIS/10.0 + strict-transport-security: + - max-age=31536000; includeSubDomains + transfer-encoding: + - chunked + vary: + - Accept-Encoding,Accept-Encoding + x-content-type-options: + - nosniff + x-powered-by: + - ASP.NET + status: + code: 200 + message: OK - request: body: null headers: @@ -59,7 +107,7 @@ interactions: ParameterSetName: - --resource --namespace User-Agent: - - AZURECLI/2.19.1 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metricDefinitions?api-version=2018-01-01&metricnamespace=Microsoft.Storage%2FstorageAccounts response: @@ -107,7 +155,7 @@ interactions: content-type: - application/json date: - - Mon, 22 Feb 2021 11:26:30 GMT + - Fri, 26 Mar 2021 06:44:18 GMT request-context: - appId=cid-v1:b021da79-5252-4375-9df5-2e17c1dcd822 server: @@ -141,12 +189,12 @@ interactions: ParameterSetName: - --resource --namespace --metrics --start-time --end-time User-Agent: - - AZURECLI/2.19.1 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metrics?timespan=2018-01-01T00%253A00%253A00%252B00%253A00%252F2999-01-01T00%253A00%253A00%252B00%253A00&interval=PT1M&metricnames=Ingress%2CEgress&top=10&api-version=2018-01-01&metricnamespace=Microsoft.Storage%2FstorageAccounts response: body: - string: '{"cost":0,"timespan":"2998-12-01T00:00:00Z/2999-01-01T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The + string: '{"cost":89278,"timespan":"2998-12-01T00:00:00Z/2999-01-01T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The amount of ingress data, in bytes. This number includes ingress from an external client into Azure Storage as well as ingress within Azure.","unit":"Bytes","timeseries":[],"errorCode":"Success"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Egress","type":"Microsoft.Insights/metrics","name":{"value":"Egress","localizedValue":"Egress"},"displayDescription":"The amount of egress data. This number includes egress to external client from @@ -158,11 +206,11 @@ interactions: cache-control: - no-cache content-length: - - '1355' + - '1359' content-type: - application/json date: - - Mon, 22 Feb 2021 11:26:32 GMT + - Fri, 26 Mar 2021 06:44:19 GMT request-context: - appId=cid-v1:b021da79-5252-4375-9df5-2e17c1dcd822 server: @@ -196,12 +244,12 @@ interactions: ParameterSetName: - --resource --metrics --start-time --offset User-Agent: - - AZURECLI/2.19.1 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metrics?timespan=2018-01-01T00%253A00%253A00%252B00%253A00%252F2031-09-10T00%253A00%253A00%252B00%253A00&interval=PT1M&metricnames=Ingress%2CEgress&top=10&api-version=2018-01-01 response: body: - string: '{"cost":0,"timespan":"2031-08-10T00:00:00Z/2031-09-10T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The + string: '{"cost":89278,"timespan":"2031-08-10T00:00:00Z/2031-09-10T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The amount of ingress data, in bytes. This number includes ingress from an external client into Azure Storage as well as ingress within Azure.","unit":"Bytes","timeseries":[],"errorCode":"Success"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Egress","type":"Microsoft.Insights/metrics","name":{"value":"Egress","localizedValue":"Egress"},"displayDescription":"The amount of egress data. This number includes egress to external client from @@ -213,11 +261,11 @@ interactions: cache-control: - no-cache content-length: - - '1355' + - '1359' content-type: - application/json date: - - Mon, 22 Feb 2021 11:26:32 GMT + - Fri, 26 Mar 2021 06:44:20 GMT request-context: - appId=cid-v1:b021da79-5252-4375-9df5-2e17c1dcd822 server: @@ -251,12 +299,12 @@ interactions: ParameterSetName: - --resource --metrics --end-time --offset User-Agent: - - AZURECLI/2.19.1 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.7.7 (Windows-10-10.0.19041-SP0) + - AZURECLI/2.21.0 azsdk-python-azure-mgmt-monitor/2.0.0 Python/3.8.8 (Windows-10-10.0.19041-SP0) method: GET uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/microsoft.insights/metrics?timespan=2011-04-25T00%253A00%253A00%252B00%253A00%252F2025-01-01T00%253A00%253A00%252B00%253A00&interval=PT1M&metricnames=Ingress%2CEgress&top=10&api-version=2018-01-01 response: body: - string: '{"cost":0,"timespan":"2024-12-01T00:00:00Z/2025-01-01T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The + string: '{"cost":89278,"timespan":"2024-12-01T00:00:00Z/2025-01-01T00:00:00Z","interval":"PT1M","value":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Ingress","type":"Microsoft.Insights/metrics","name":{"value":"Ingress","localizedValue":"Ingress"},"displayDescription":"The amount of ingress data, in bytes. This number includes ingress from an external client into Azure Storage as well as ingress within Azure.","unit":"Bytes","timeseries":[],"errorCode":"Success"},{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/clitest.rg000001/providers/Microsoft.Storage/storageAccounts/clitest000002/providers/Microsoft.Insights/metrics/Egress","type":"Microsoft.Insights/metrics","name":{"value":"Egress","localizedValue":"Egress"},"displayDescription":"The amount of egress data. This number includes egress to external client from @@ -268,11 +316,11 @@ interactions: cache-control: - no-cache content-length: - - '1355' + - '1359' content-type: - application/json date: - - Mon, 22 Feb 2021 11:26:33 GMT + - Fri, 26 Mar 2021 06:44:22 GMT request-context: - appId=cid-v1:b021da79-5252-4375-9df5-2e17c1dcd822 server: diff --git a/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/test_monitor_metrics.py b/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/test_monitor_metrics.py index 308e27bae17..aa1d8697cbf 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/test_monitor_metrics.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/tests/latest/test_monitor_metrics.py @@ -7,13 +7,15 @@ class TestMonitorMetrics(ScenarioTest): - @ResourceGroupPreparer(location='southcentralus') + + @ResourceGroupPreparer() @StorageAccountPreparer() def test_monitor_metrics_scenario(self, resource_group, storage_account): self.kwargs.update({}) self.kwargs['sa_id'] = self.cmd('az storage account show -n {sa} -g {rg}').get_output_in_json()['id'] - self.cmd('az monitor metrics list-definitions --resource {sa_id} --namespace Microsoft.Storage/storageAccounts') - self.cmd('az monitor metrics list --resource {sa_id} --namespace Microsoft.Storage/storageAccounts --metrics Ingress Egress --start-time 2018-01-01T00:00:00Z --end-time 2999-01-01T00:00:00Z', + self.kwargs['namespace'] = self.cmd('az monitor metrics list-namespaces --resource {sa_id}').get_output_in_json()[0]['properties']['metricNamespaceName'] + self.cmd('az monitor metrics list-definitions --resource {sa_id} --namespace {namespace}') + self.cmd('az monitor metrics list --resource {sa_id} --namespace {namespace} --metrics Ingress Egress --start-time 2018-01-01T00:00:00Z --end-time 2999-01-01T00:00:00Z', checks=self.check('length(@.value)', 2)) self.cmd('az monitor metrics list --resource {sa_id} --metrics Ingress Egress --start-time 2018-01-01 00:00:00 +00:00 --offset 5000d', checks=self.check('length(@.value)', 2)) diff --git a/src/azure-cli/azure/cli/command_modules/monitor/transformers.py b/src/azure-cli/azure/cli/command_modules/monitor/transformers.py index bb26870132c..e1c887d8efc 100644 --- a/src/azure-cli/azure/cli/command_modules/monitor/transformers.py +++ b/src/azure-cli/azure/cli/command_modules/monitor/transformers.py @@ -69,6 +69,16 @@ def row_convert(item): return _generic_table_convert(results, row_convert) +def metrics_namespaces_table(results): + def row_convert(item): + from collections import OrderedDict + result = OrderedDict() + result['Classification'] = item['classification'] + result['Metric Namespace Name'] = item['properties']['metricNamespaceName'] + return result + return _generic_table_convert(results, row_convert) + + def metrics_table(results): from collections import OrderedDict