import json import unittest import alerta_azuremonitor from alerta.app import create_app, custom_webhooks class AzureMonitoringWebhookTestCase(unittest.TestCase): def setUp(self): test_config = { 'TESTING': True, 'AUTH_REQUIRED': False } self.app = create_app(test_config) self.client = self.app.test_client() custom_webhooks.webhooks['azuremonitor'] = alerta_azuremonitor.AzureMonitorWebhook() def test_azuremonitor_webhook_classic(self): """ See https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-webhooks """ classic_metric_alert = r""" { "status": "Activated", "context": { "timestamp": "2015-08-14T22:26:41.9975398Z", "id": "/subscriptions/s1/resourceGroups/useast/providers/microsoft.insights/alertrules/ruleName1", "name": "ruleName1", "description": "some description", "conditionType": "Metric", "condition": { "metricName": "Requests", "metricUnit": "Count", "metricValue": "10", "threshold": "10", "windowSize": "15", "timeAggregation": "Average", "operator": "GreaterThanOrEqual" }, "subscriptionId": "s1", "resourceGroupName": "useast", "resourceName": "mysite1", "resourceType": "microsoft.foo/sites", "resourceId": "/subscriptions/s1/resourceGroups/useast/providers/microsoft.foo/sites/mysite1", "resourceRegion": "centralus", "portalLink": "https://portal.azure.com/#resource/subscriptions/s1/resourceGroups/useast/providers/microsoft.foo/sites/mysite1" }, "properties": { "key1": "value1", "key2": "value2" } } """ response = self.client.post('/webhooks/azuremonitor', data=classic_metric_alert, content_type='application/json') self.assertEqual(response.status_code, 201, response.data) data = json.loads(response.data.decode('utf-8')) self.assertEqual(data['alert']['resource'], 'mysite1') self.assertEqual(data['alert']['event'], 'ruleName1') self.assertEqual(data['alert']['environment'], 'Production') self.assertEqual(data['alert']['severity'], 'critical') self.assertEqual(data['alert']['status'], 'open') self.assertEqual(data['alert']['service'], ['microsoft.foo/sites']) self.assertEqual(data['alert']['group'], 'useast') self.assertEqual(data['alert']['value'], '10 Requests') self.assertEqual(data['alert']['text'], 'CRITICAL: 10 Requests (GreaterThanOrEqual 10)') self.assertEqual(sorted(data['alert']['tags']), ['key1=value1', 'key2=value2']) classic_metric_alert = r""" { "status": "Activated", "context": { "id": "/subscriptions/1a66ce04-b633-4a0b-b2bc-a912ec8986a6/resourceGroups/montest/providers/microsoft.insights/alertrules/Alert_1_runscope12", "name": "Alert_1_runscope12", "description": "desc", "conditionType": "Metric", "condition": { "metricName": "Memory available", "metricUnit": "Bytes", "metricValue": "1032190976", "threshold": "2", "windowSize": "5", "timeAggregation": "Average", "operator": "GreaterThan" }, "subscriptionId": "1a66ce04-b633-4a0b-b2bc-a912ec8986a6", "resourceGroupName": "montest", "timestamp": "2015-09-18T01:02:35.8190994Z", "resourceName": "helixtest1", "resourceType": "microsoft.compute/virtualmachines", "resourceId": "/subscriptions/1a66ce04-b633-4a0b-b2bc-a912ec8986a6/resourceGroups/montest/providers/Microsoft.Compute/virtualMachines/Helixtest1", "resourceRegion": "centralus", "portalLink": "http://portallink.com" }, "properties": { "hello1": "World1!", "json_stuff": { "color": "red" }, "customId": "wd39ue9832ue9iuhd9iuewhd9edh", "send_emails_to": "someone@somewhere.com" } } """ response = self.client.post('/webhooks/azuremonitor', data=classic_metric_alert, content_type='application/json') self.assertEqual(response.status_code, 201, response.data) data = json.loads(response.data.decode('utf-8')) self.assertEqual(data['alert']['resource'], 'helixtest1') self.assertEqual(data['alert']['event'], 'Alert_1_runscope12') self.assertEqual(data['alert']['environment'], 'Production') self.assertEqual(data['alert']['severity'], 'critical') self.assertEqual(data['alert']['status'], 'open') self.assertEqual(data['alert']['service'], ['microsoft.compute/virtualmachines']) self.assertEqual(data['alert']['group'], 'montest') self.assertEqual(data['alert']['value'], '1032190976 Memory available') self.assertEqual(data['alert']['text'], 'CRITICAL: 1032190976 Memory available (GreaterThan 2)') self.assertEqual(sorted(data['alert']['tags']), [ 'customId=wd39ue9832ue9iuhd9iuewhd9edh', 'hello1=World1!', "json_stuff={'color': 'red'}", 'send_emails_to=someone@somewhere.com'] ) def test_azuremonitor_webhook_new(self): """ See https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-metric-near-real-time """ new_metric_alert = r""" { "schemaId": "AzureMonitorMetricAlert", "data": { "version": "2.0", "status": "Activated", "context": { "timestamp": "2018-02-28T10:44:10.1714014Z", "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/Contoso/providers/microsoft.insights/metricAlerts/StorageCheck", "name": "StorageCheck", "description": "", "conditionType": "SingleResourceMultipleMetricCriteria", "condition": { "windowSize": "PT5M", "allOf": [ { "metricName": "Transactions", "dimensions": [ { "name": "AccountResourceId", "value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/Contoso/providers/Microsoft.Storage/storageAccounts/diag500" }, { "name": "GeoType", "value": "Primary" } ], "operator": "GreaterThan", "threshold": "0", "timeAggregation": "PT5M", "metricValue": 1 } ] }, "subscriptionId": "00000000-0000-0000-0000-000000000000", "resourceGroupName": "Contoso", "resourceName": "diag500", "resourceType": "Microsoft.Storage/storageAccounts", "resourceId": "/subscriptions/1e3ff1c0-771a-4119-a03b-be82a51e232d/resourceGroups/Contoso/providers/Microsoft.Storage/storageAccounts/diag500", "portalLink": "https://portal.azure.com/#resource//subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/Contoso/providers/Microsoft.Storage/storageAccounts/diag500" }, "properties": { "key1": "value1", "key2": "value2" } } } """ response = self.client.post('/webhooks/azuremonitor', data=new_metric_alert, content_type='application/json') self.assertEqual(response.status_code, 201, response.data) data = json.loads(response.data.decode('utf-8')) self.assertEqual(data['alert']['resource'], 'diag500') self.assertEqual(data['alert']['event'], 'StorageCheck') self.assertEqual(data['alert']['environment'], 'Production') self.assertEqual(data['alert']['severity'], 'informational') self.assertEqual(data['alert']['status'], 'open') self.assertEqual(data['alert']['service'], ['Microsoft.Storage/storageAccounts']) self.assertEqual(data['alert']['group'], 'Contoso') self.assertEqual(data['alert']['value'], '1 Transactions') self.assertEqual(data['alert']['text'], 'INFORMATIONAL: 1 Transactions (GreaterThan 0)') self.assertEqual(sorted(data['alert']['tags']), ['key1=value1', 'key2=value2']) new_metric_alert = r""" { "schemaId": "AzureMonitorMetricAlert", "data": { "version": "2.0", "properties": null, "status": "Deactivated", "context": { "timestamp": "2019-02-27T14:10:35.0816694Z", "id": "/subscriptions/ba364c14-1aa5-484e-8b74-6201540087e1/resourceGroups/Web/providers/microsoft.insights/metricAlerts/Percentage%20CPU%20greater%20than%2070", "name": "CpuUtilHigh", "description": "", "conditionType": "MultipleResourceMultipleMetricCriteria", "severity": "3", "condition": { "windowSize": "PT5M", "allOf": [ { "metricName": "Percentage CPU", "metricNamespace": "Microsoft.Compute/virtualMachines", "operator": "GreaterThan", "threshold": "90", "timeAggregation": "Maximum", "dimensions": [ { "name": "microsoft.resourceId", "value": "/subscriptions/ba364c14-1aa5-484e-8b74-6201540087e1/resourceGroups/Web/providers/Microsoft.Compute/virtualMachines/web01" }, { "name": "microsoft.resourceType", "value": "Microsoft.Compute/virtualMachines" } ], "metricValue": 85 } ] }, "subscriptionId": "ba364c14-1aa5-484e-8b74-6201540087e1", "resourceGroupName": "Web", "resourceName": "web01", "resourceType": "Microsoft.Compute/virtualMachines", "resourceId": "/subscriptions/ba364c14-1aa5-484e-8b74-6201540087e1/resourceGroups/Web/providers/Microsoft.Compute/virtualMachines/web01", "portalLink": "https://portal.azure.com/#resource/subscriptions/ba364c14-1aa5-484e-8b74-6201540087e1/resourceGroups/Web/providers/Microsoft.Compute/virtualMachines/web01" } } } """ response = self.client.post('/webhooks/azuremonitor?environment=Development', data=new_metric_alert, content_type='application/json') self.assertEqual(response.status_code, 201, response.data) data = json.loads(response.data.decode('utf-8')) self.assertEqual(data['alert']['resource'], 'web01') self.assertEqual(data['alert']['event'], 'CpuUtilHigh') self.assertEqual(data['alert']['environment'], 'Development') self.assertEqual(data['alert']['severity'], 'ok') self.assertEqual(data['alert']['status'], 'closed') self.assertEqual(data['alert']['service'], ['Microsoft.Compute/virtualMachines']) self.assertEqual(data['alert']['group'], 'Web') self.assertEqual(data['alert']['value'], '85 Percentage CPU') self.assertEqual(data['alert']['text'], 'OK: 85 Percentage CPU (GreaterThan 90)') self.assertEqual(sorted(data['alert']['tags']), [])