From 52324066d89f21ac653aefdfce03de535b453ed4 Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Tue, 9 Apr 2019 11:12:54 +0100 Subject: [PATCH] Extends the GET alerts API endpoint --- src/service/clmcservice/alertsapi/tests.py | 26 +++++++++------------- src/service/clmcservice/alertsapi/views.py | 14 +++++++++--- src/test/clmctest/alerts/test_alerts.py | 10 +++++++++ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/service/clmcservice/alertsapi/tests.py b/src/service/clmcservice/alertsapi/tests.py index 64683d2..a24b597 100644 --- a/src/service/clmcservice/alertsapi/tests.py +++ b/src/service/clmcservice/alertsapi/tests.py @@ -302,6 +302,9 @@ class TestAlertsConfigurationAPI(object): kapacitor_host = self.config.registry.settings["kapacitor_host"] kapacitor_port = self.config.registry.settings["kapacitor_port"] + sfemc_fqdn = self.config.registry.settings["sfemc_fqdn"] + sfemc_port = self.config.registry.settings["sfemc_port"] + fqdn_prefix = "http://{0}:{1}/sfemc/event".format(sfemc_fqdn, sfemc_port) # test all of the test files provided by the path_generator_testfiles function, ignoring the last result, which is invalid resource spec. files for alert_spec_file_paths, valid_resource_spec_file_paths, _ in path_generator_testfiles(): @@ -338,12 +341,19 @@ class TestAlertsConfigurationAPI(object): # restructure the extracted alerts data to be comparable with the response of the clmc service expected_alerts = map(lambda alert_object: { "policy": alert_object["policy"], "trigger": alert_object["trigger"], + # make sure handlers are sorted and replace URLs starting with the SFEMC fqdn prefix to the SFEMC label + "handlers": sorted(map(lambda handler: SFEMC if handler.startswith(fqdn_prefix) else handler, alert_object["handlers"].values())), "task_identifier": alert_object["task"], "topic_identifier": alert_object["topic"], "task_api_endpoint": "/kapacitor/v1/tasks/{0}".format(alert_object["task"]), "topic_api_endpoint": "/kapacitor/v1/alerts/topics/{0}".format(alert_object["topic"]), "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/{0}/handlers".format(alert_object["topic"]) }, alerts) expected_alerts = sorted(expected_alerts, key=lambda x: x["trigger"]) + # sort the handlers of each alert in the response to ensure comparison order is correct + for alert in response: + alert["handlers"] = sorted(alert["handlers"]) + + # compare the actual response with the expected response assert sorted(response, key=lambda x: x["trigger"]) == expected_alerts, "Incorrect result returned from a GET alerts request" clean_kapacitor_alerts(alerts, kapacitor_host, kapacitor_port) @@ -388,21 +398,7 @@ class TestAlertsConfigurationAPI(object): # ensure that these resource (tasks, topics, handlers) exist in Kapacitor # traverse through all alerts and check that everything is created - for alert in alerts: - # check the alert task - alert_id = alert["task"] - kapacitor_response = get("http://{0}:{1}/kapacitor/v1/tasks/{2}".format(kapacitor_host, kapacitor_port, alert_id)) - assert kapacitor_response.status_code == 200, "Alert with ID {0} was not created - test file {1}.".format(alert_id, alerts_test_file) - - # check the alert topic - topic_id = alert["topic"] - kapacitor_response = get("http://{0}:{1}/kapacitor/v1/alerts/topics/{2}".format(kapacitor_host, kapacitor_port, topic_id)) - assert kapacitor_response.status_code == 200, "Topic with ID {0} was not created - test file {1}".format(topic_id, alerts_test_file) - - # check handlers - for handler_id in alert["handlers"]: - kapacitor_response = get("http://{0}:{1}/kapacitor/v1/alerts/topics/{2}/handlers/{3}".format(kapacitor_host, kapacitor_port, topic_id, handler_id)) - assert kapacitor_response.status_code == 200, "Handler with ID {0} for topic with ID {1} was not created - test file {2}".format(handler_id, topic_id, alerts_test_file) + check_kapacitor_alerts(alerts, kapacitor_host, kapacitor_port, alerts_test_file) with open(alert_spec_abs_path) as alert_spec: # now send the alert spec for deletion and check that everything is deleted in Kapacitor diff --git a/src/service/clmcservice/alertsapi/views.py b/src/service/clmcservice/alertsapi/views.py index c984dc8..71a2a77 100644 --- a/src/service/clmcservice/alertsapi/views.py +++ b/src/service/clmcservice/alertsapi/views.py @@ -98,6 +98,8 @@ class AlertsConfigurationAPI(object): """ kapacitor_host, kapacitor_port = self.request.registry.settings['kapacitor_host'], self.request.registry.settings['kapacitor_port'] + sfemc_fqdn, sfemc_port = self.request.registry.settings['sfemc_fqdn'], self.request.registry.settings['sfemc_port'] + fqdn_prefix = "http://{0}:{1}/sfemc/event".format(sfemc_fqdn, sfemc_port) # fetch the URL parameters sfc_id, sfc_instance_id = self.request.matchdict["sfc_id"], self.request.matchdict["sfc_instance_id"] @@ -123,12 +125,17 @@ class AlertsConfigurationAPI(object): policy_id = task_config["policy"]["value"] trigger_id = task_config["eventID"]["value"] + kapacitor_handlers_relative_url = "/kapacitor/v1/alerts/topics/{0}/handlers".format(topic_id) + kapacitor_handlers_full_url = "http://{0}:{1}{2}".format(kapacitor_host, kapacitor_port, kapacitor_handlers_relative_url) + handlers = [handler_obj["options"]["url"] for handler_obj in get(kapacitor_handlers_full_url).json()["handlers"]] + handlers = list(map(lambda handler: SFEMC if handler.startswith(fqdn_prefix) else handler, handlers)) + # add it to the list of alerts for this SFC instance - sfc_instance_tasks.append({"policy": policy_id, "trigger": trigger_id, + sfc_instance_tasks.append({"policy": policy_id, "trigger": trigger_id, "handlers": handlers, "task_identifier": task_id, "topic_identifier": topic_id, "task_api_endpoint": "/kapacitor/v1/tasks/{0}".format(task_id), "topic_api_endpoint": "/kapacitor/v1/alerts/topics/{0}".format(topic_id), - "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/{0}/handlers".format(topic_id)}) + "topic_handlers_api_endpoint": kapacitor_handlers_relative_url}) return sfc_instance_tasks @@ -144,6 +151,7 @@ class AlertsConfigurationAPI(object): kapacitor_host, kapacitor_port = self.request.registry.settings['kapacitor_host'], self.request.registry.settings['kapacitor_port'] sfemc_fqdn, sfemc_port = self.request.registry.settings['sfemc_fqdn'], self.request.registry.settings['sfemc_port'] + fqdn_prefix = "http://{0}:{1}/sfemc/event".format(sfemc_fqdn, sfemc_port) # since this is not a POST request, need to fetch the alert specification file from request.params, rather than request.POST alert_spec_reference = self.request.params.get('alert-spec') @@ -185,7 +193,7 @@ class AlertsConfigurationAPI(object): for handler in http_handlers: original_http_handler_url = handler["options"]["url"] - if original_http_handler_url.startswith("http://{0}:{1}/".format(sfemc_fqdn, sfemc_port)): + if original_http_handler_url.startswith(fqdn_prefix): original_http_handler_url = SFEMC handler_id = handler["id"] diff --git a/src/test/clmctest/alerts/test_alerts.py b/src/test/clmctest/alerts/test_alerts.py index db664a6..808ab25 100644 --- a/src/test/clmctest/alerts/test_alerts.py +++ b/src/test/clmctest/alerts/test_alerts.py @@ -133,23 +133,33 @@ class TestAlerts(object): assert response.status_code == 200 clmc_service_response = response.json() clmc_service_response = sorted(clmc_service_response, key=lambda x: x["trigger"]) # sort by trigger so that the response can be compared to what's expected + + # sort the handlers of returned alerts to ensure comparison order is correct + for alert in clmc_service_response: + alert["handlers"] = sorted(alert["handlers"]) + + # compare actual response with expected response assert clmc_service_response == [ {"policy": "scale_nginx_policy", "trigger": "high_requests", "task_identifier": "46fb8800c8a5eeeb04b090d838d475df574a2e6d854b5d678fc981c096eb6c1b", + "handlers": ["http://172.40.231.200:9999/"], "topic_identifier": "46fb8800c8a5eeeb04b090d838d475df574a2e6d854b5d678fc981c096eb6c1b", "task_api_endpoint": "/kapacitor/v1/tasks/46fb8800c8a5eeeb04b090d838d475df574a2e6d854b5d678fc981c096eb6c1b", "topic_api_endpoint": "/kapacitor/v1/alerts/topics/46fb8800c8a5eeeb04b090d838d475df574a2e6d854b5d678fc981c096eb6c1b", "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/46fb8800c8a5eeeb04b090d838d475df574a2e6d854b5d678fc981c096eb6c1b/handlers"}, {"policy": "scale_nginx_policy", "trigger": "increase_in_active_requests", "task_identifier": "7a9867f9270dba6635ac3760a3b70bc929f5bd0f3bf582e45d27fbd437f528ca", + "handlers": ["flame_sfemc", "http://172.40.231.200:9999/"], "topic_identifier": "7a9867f9270dba6635ac3760a3b70bc929f5bd0f3bf582e45d27fbd437f528ca", "task_api_endpoint": "/kapacitor/v1/tasks/7a9867f9270dba6635ac3760a3b70bc929f5bd0f3bf582e45d27fbd437f528ca", "topic_api_endpoint": "/kapacitor/v1/alerts/topics/7a9867f9270dba6635ac3760a3b70bc929f5bd0f3bf582e45d27fbd437f528ca", "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/7a9867f9270dba6635ac3760a3b70bc929f5bd0f3bf582e45d27fbd437f528ca/handlers"}, {"policy": "scale_nginx_policy", "trigger": "increase_in_running_processes", "task_identifier": "f5edaeb27fb847116be749c3815d240cbf0d7ba79aee1959daf0b3445a70f2c8", + "handlers": ["flame_sfemc", "http://172.40.231.200:9999/"], "topic_identifier": "f5edaeb27fb847116be749c3815d240cbf0d7ba79aee1959daf0b3445a70f2c8", "task_api_endpoint": "/kapacitor/v1/tasks/f5edaeb27fb847116be749c3815d240cbf0d7ba79aee1959daf0b3445a70f2c8", "topic_api_endpoint": "/kapacitor/v1/alerts/topics/f5edaeb27fb847116be749c3815d240cbf0d7ba79aee1959daf0b3445a70f2c8", "topic_handlers_api_endpoint": "/kapacitor/v1/alerts/topics/f5edaeb27fb847116be749c3815d240cbf0d7ba79aee1959daf0b3445a70f2c8/handlers"}, {"policy": "deadman_policy", "trigger": "no_measurements", "task_identifier": "f7dab6fd53001c812d44533d3bbb6ef45f0d1d39b9441bc3c60402ebda85d320", + "handlers": ["flame_sfemc", "http://172.40.231.200:9999/"], "topic_identifier": "f7dab6fd53001c812d44533d3bbb6ef45f0d1d39b9441bc3c60402ebda85d320", "task_api_endpoint": "/kapacitor/v1/tasks/f7dab6fd53001c812d44533d3bbb6ef45f0d1d39b9441bc3c60402ebda85d320", "topic_api_endpoint": "/kapacitor/v1/alerts/topics/f7dab6fd53001c812d44533d3bbb6ef45f0d1d39b9441bc3c60402ebda85d320", -- GitLab