From 51ec331e6f402e876daa02b539a39a272e27b17e Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Fri, 17 Aug 2018 16:31:07 +0100 Subject: [PATCH] Initial implementation of the alerts API - WIP, to be tested --- .gitignore | 2 +- src/service/MANIFEST.in | 5 +- src/service/clmcservice/VERSION | 1 + src/service/clmcservice/__init__.py | 20 +- src/service/clmcservice/alertsapi/__init__.py | 0 .../alertsapi/alerts_specification_schema.py | 189 ++++++++++++++++++ src/service/clmcservice/alertsapi/tests.py | 133 ++++++++++++ .../clmcservice/alertsapi/utilities.py | 81 ++++++++ src/service/clmcservice/alertsapi/views.py | 139 +++++++++++++ .../TICKscript/threshold_template.tick | 29 +++ .../tosca/flame_clmc_alerts_definitions.yaml | 11 + .../invalid/alerts_test_config-1.yaml | 53 +++++ .../invalid/alerts_test_config-10.yaml | 54 +++++ .../invalid/alerts_test_config-2.yaml | 53 +++++ .../invalid/alerts_test_config-3.yaml | 35 ++++ .../invalid/alerts_test_config-4.yaml | 35 ++++ .../invalid/alerts_test_config-5.yaml | 36 ++++ .../invalid/alerts_test_config-6.yaml | 53 +++++ .../invalid/alerts_test_config-7.yaml | 54 +++++ .../invalid/alerts_test_config-8.yaml | 40 ++++ .../invalid/alerts_test_config-9.yaml | 52 +++++ .../valid/alerts_test_config-1.yaml | 54 +++++ .../valid/alerts_test_config-2.yaml | 56 ++++++ .../valid/alerts_test_config-3.yaml | 52 +++++ .../valid/alerts_test_config-4.yaml | 49 +++++ .../valid/alerts_test_config-5.yaml | 49 +++++ .../invalid/alerts_test_config-1.yaml | 40 ++++ .../invalid/alerts_test_config-2.yaml | 53 +++++ .../invalid/alerts_test_config-3.yaml | 53 +++++ .../invalid/alerts_test_config-4.yaml | 54 +++++ .../valid/alerts_test_config-1.yaml | 54 +++++ .../valid/alerts_test_config-2.yaml | 48 +++++ .../valid/alerts_test_config-3.yaml | 30 +++ .../valid/alerts_test_config-4.yaml | 35 ++++ src/service/setup.py | 30 ++- src/test/clmctest/alerts/alert_example.tick | 13 -- src/test/clmctest/alerts/configuration.json | 43 ---- src/test/clmctest/alerts/handler_example.yaml | 7 - src/test/clmctest/alerts/http_server.py | 37 ---- .../alerts/threshold_configuration.json | 8 - .../clmctest/alerts/threshold_template.tick | 26 --- 41 files changed, 1715 insertions(+), 151 deletions(-) create mode 100644 src/service/clmcservice/VERSION create mode 100644 src/service/clmcservice/alertsapi/__init__.py create mode 100644 src/service/clmcservice/alertsapi/alerts_specification_schema.py create mode 100644 src/service/clmcservice/alertsapi/tests.py create mode 100644 src/service/clmcservice/alertsapi/utilities.py create mode 100644 src/service/clmcservice/alertsapi/views.py create mode 100644 src/service/clmcservice/resources/TICKscript/threshold_template.tick create mode 100644 src/service/clmcservice/resources/tosca/flame_clmc_alerts_definitions.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-1.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-10.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-2.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-3.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-4.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-5.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-6.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-7.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-8.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-9.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-1.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-2.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-3.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-4.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-5.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-1.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-2.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-3.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-4.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-1.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-2.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-3.yaml create mode 100644 src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-4.yaml delete mode 100644 src/test/clmctest/alerts/alert_example.tick delete mode 100644 src/test/clmctest/alerts/configuration.json delete mode 100644 src/test/clmctest/alerts/handler_example.yaml delete mode 100644 src/test/clmctest/alerts/http_server.py delete mode 100644 src/test/clmctest/alerts/threshold_configuration.json delete mode 100644 src/test/clmctest/alerts/threshold_template.tick diff --git a/.gitignore b/.gitignore index 0694a2d..1cfef0b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ *egg-info* *git-commit-ref* *_version.py* -ubuntu-xenial-16.04-cloudimg-console.log +ubuntu-bionic-18.04-cloudimg-console.log .idea/ *.egg *.pyc diff --git a/src/service/MANIFEST.in b/src/service/MANIFEST.in index eaf16db..2d2b4a8 100644 --- a/src/service/MANIFEST.in +++ b/src/service/MANIFEST.in @@ -1,2 +1,3 @@ -include MANIFEST.in -recursive-include clmcservice \ No newline at end of file +include clmcservice/resources/tosca/flame_clmc_alerts_definitions.yaml +include clmcservice/VERSION +recursive-include clmcservice/resources/TICKscript *_template.tick \ No newline at end of file diff --git a/src/service/clmcservice/VERSION b/src/service/clmcservice/VERSION new file mode 100644 index 0000000..4a2bfa8 --- /dev/null +++ b/src/service/clmcservice/VERSION @@ -0,0 +1 @@ +__version__ = "1.2.0" \ No newline at end of file diff --git a/src/service/clmcservice/__init__.py b/src/service/clmcservice/__init__.py index ff5cee8..9435423 100644 --- a/src/service/clmcservice/__init__.py +++ b/src/service/clmcservice/__init__.py @@ -22,12 +22,21 @@ // Created for Project : FLAME """ -from os import path + +# Python standard libs from json import load +from os.path import dirname, abspath + +# PIP installed libs from pyramid.config import Configurator from sqlalchemy import engine_from_config + +# CLMC-service imports from clmcservice.models.meta import DBSession, Base -from clmcservice.aggregationapi.utilities import validate_conf_file, RUNNING_FLAG, MALFORMED_FLAG, CONF_FILE_ATTRIBUTE, CONF_OBJECT, AGGREGATOR_CONFIG_SECTION +from clmcservice.aggregationapi.utilities import validate_conf_file, MALFORMED_FLAG, CONF_FILE_ATTRIBUTE, CONF_OBJECT + + +ROOT_DIR = dirname(abspath(__file__)) # get the path of the root package (clmcservice) as a global variable def main(global_config, **settings): @@ -62,14 +71,13 @@ def main(global_config, **settings): config.add_route('whoami_endpoints', '/whoami/endpoints') config.add_route('whoami_endpoints_instance', 'whoami/endpoints/instance') - # add routes of the CONFIG API - config.add_route('config_sfc', '/config/sf-chains') - config.add_route('config_sfc_instance', '/config/sf-chains/instance') - # add routes of the GRAPH API config.add_route('graph_build', '/graph/temporal') config.add_route('graph_manage', '/graph/temporal/{graph_id}') config.add_route('graph_algorithms_rtt', '/graph/temporal/{graph_id}/round-trip-time') + # add routes of the Alerts Configuration API + config.add_route('alerts_configuration', '/alerts') + config.scan() # This method scans the packages and finds any views related to the routes added in the app configuration return config.make_wsgi_app() diff --git a/src/service/clmcservice/alertsapi/__init__.py b/src/service/clmcservice/alertsapi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/service/clmcservice/alertsapi/alerts_specification_schema.py b/src/service/clmcservice/alertsapi/alerts_specification_schema.py new file mode 100644 index 0000000..ed17c3a --- /dev/null +++ b/src/service/clmcservice/alertsapi/alerts_specification_schema.py @@ -0,0 +1,189 @@ +#!/usr/bin/python3 +""" +// © University of Southampton IT Innovation Centre, 2018 +// +// Copyright in this software belongs to University of Southampton +// IT Innovation Centre of Gamma House, Enterprise Road, +// Chilworth Science Park, Southampton, SO16 7NS, UK. +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Nikolay Stanchev +// Created Date : 16-08-2018 +// Created for Project : FLAME +""" + + +# Python standard libs +from re import compile, IGNORECASE + +# PIP installed libs +from schema import Schema, And, Or, Optional + + +""" +This module defines the schema objects for the TOSCA Alert Specification: + + * flame_clmc_alerts_definitions.yaml must be the only import + * metadata section must be present (with key-value pairs for sfc and sfci) + * policies section must be present (under the topology_template node) + * each policy must be associated with a triggers node (containing at least 1 trigger) + * each policy is of type eu.ict-flame.policies.StateChange or eu.ict-flame.policies.Alert + * each trigger must specify event_type, metric, condition, and at least one handler in action/implementation + * the condition section must specify threshold, granularity, aggregation_method, comparison_operator +""" + + +# Influx QL functions defined in the documentation https://docs.influxdata.com/influxdb/v1.6/query_language/functions/ +INFLUX_QL_FUNCTIONS = ( + "count", "mean", "median", "mode", "sum", "first", "last", "max", "min" +) + +# Kapacitor Tick Script template IDs +TICK_SCRIPT_TEMPLATES = ("threshold", "relative", "deadman") + +# Allowed comparison operators and their logical values +COMPARISON_OPERATORS = {"lt": "<", "gt": ">", "lte": "<=", "gte": ">=", "eq": "=", "neq": "<>"} + +# Regular expression for validating http handlers +URL_REGEX = compile( + r'^https?://' # http:// or https:// + r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain, e.g. example.domain.com + r'localhost|' # or localhost... + r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # or IP address (IPv4 format) + r'(?::\d{2,5})?' # optional port number + r'(?:[/?#][^\s]*)?$', # URL path or query parameters + IGNORECASE) + + +# Global tags allowed to be used for filtering in the trigger condition +CLMC_INFORMATION_MODEL_GLOBAL_TAGS = ("sfc", "sfci", "sf_package", "sf", "sf_endpoint", "host", "location") + + +ALERTS_SPECIFICATION_SCHEMA = Schema({ + "tosca_definitions_version": And(str, lambda v: v == "tosca_simple_profile_for_nfv_1_0_0"), + Optional("description"): str, + "imports": And([lambda s: s.endswith("flame_clmc_alerts_definitions.yaml")], lambda l: len(l) == 1), + "metadata": { + "sfc": str, + "sfci": str + }, + "topology_template": { + "policies": [ + { + str: { + "type": Or("eu.ict-flame.policies.StateChange", "eu.ict-flame.policies.Alert"), + "triggers": And({ + str: { + Optional("description"): str, + "event_type": And(str, lambda s: s in TICK_SCRIPT_TEMPLATES), + "metric": And(str, lambda s: len(s.split('.', 1)) == 2), + "condition": { + "threshold": Or(int, float), + "granularity": int, + "aggregation_method": And(str, lambda s: s in INFLUX_QL_FUNCTIONS), + Optional("resource_type"): { + And(str, lambda s: s in CLMC_INFORMATION_MODEL_GLOBAL_TAGS): str + }, + "comparison_operator": And(str, lambda s: s in COMPARISON_OPERATORS) + }, + "action": { + "implementation": + [ + And(str, lambda s: URL_REGEX.match(s) is not None) + ] + } + } + }, lambda l: len(l) > 0) + } + } + ] + } +}) + + +def fill_http_post_handler_vars(handler_id, handler_url): + """ + Creates a dictionary object ready to be posted to kapacitor to create an alert handler. + + :param handler_id: handler identifier + :param handler_url: url to post alerts to + + :return: a dictionary object ready to be posted to kapacitor to create an alert handler. + """ + + return { + "id": handler_id, + "kind": "post", + "options": { + "url": handler_url + } + } + + +def fill_threshold_template_vars(db, measurement, field, influx_function, critical_value, comparison_operator, alert_period, topic_id, where_clause=None): + """ + Creates a dictionary object ready to be posted to kapacitor to create a task from template. + + :param db: db name + :param measurement: measurement name + :param field: field name + :param influx_function: influx function to use for querying + :param critical_value: critical value to compare with + :param comparison_operator: type of comparison + :param alert_period: alert period to query influx + :param topic_id: topic identifier + :param where_clause: optional argument for filtering the influx query by tag values + + :return: a dictionary object ready to be posted to kapacitor to create a task from template. + """ + + comparison_lambda = "\"real_value\" {0} {1}".format(comparison_operator, critical_value) # build up lambda string, e.g. "real_value" >= 10 + + tempalte_vars = { + "db": { + "type": "string", + "value": db + }, + "measurement": { + "type": "string", + "value": measurement + }, + "field": { + "type": "string", + "value": field + }, + "influxFunction": { + "type": "string", + "value": influx_function + }, + "comparisonLambda": { + "type": "lambda", + "value": comparison_lambda + }, + "alertPeriod": { + "type": "duration", + "value": alert_period + }, + "topicID": { + "type": "string", + "value": topic_id + } + } + + if where_clause is not None: + tempalte_vars["whereClause"] = { + "type": "string", + "value": where_clause + } + + return tempalte_vars diff --git a/src/service/clmcservice/alertsapi/tests.py b/src/service/clmcservice/alertsapi/tests.py new file mode 100644 index 0000000..5b294ac --- /dev/null +++ b/src/service/clmcservice/alertsapi/tests.py @@ -0,0 +1,133 @@ +#!/usr/bin/python3 +""" +// © University of Southampton IT Innovation Centre, 2018 +// +// Copyright in this software belongs to University of Southampton +// IT Innovation Centre of Gamma House, Enterprise Road, +// Chilworth Science Park, Southampton, SO16 7NS, UK. +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Nikolay Stanchev +// Created Date : 14-08-2018 +// Created for Project : FLAME +""" + + +# Python standard libs +from os import listdir +from os.path import isfile, join +from yaml import load + +# PIP installed libs +import pytest +from pyramid import testing +from toscaparser.tosca_template import ToscaTemplate + +# CLMC-service imports +from clmcservice.alertsapi.utilities import adjust_tosca_definitions_import, validate_clmc_alerts_specification +from clmcservice.alertsapi.views import AlertsConfigurationAPI +from clmcservice import ROOT_DIR + + +class TestAlertsConfigurationAPI(object): + """ + A pytest-implementation test for the Alerts Configuration API endpoints. + """ + + @pytest.fixture(autouse=True) + def print_fixture(self): + """ + Fixture to adjust the printing format when running pytest with the "-s" flag - by default print messages mix up with pytest's output + """ + + print() + + @pytest.fixture() + def app_config(self): + """ + A fixture to implement setUp/tearDown functionality for all tests by initializing configuration structure for the web service + """ + + self.registry = testing.setUp() + + yield + + testing.tearDown() + + def test_alerts_config_tosca_parsing(self): + """ + Tests that what we consider a valid/invalid alerts specification is successfully/unsuccessfully parsed by the TOSCA-parser. + """ + + for path_suffix, valid_expected in (("valid", True), ("invalid", False)): + test_data_path = join(ROOT_DIR, *["resources", "tosca", "test-data", "tosca-parser", path_suffix]) + + for test_file_path in listdir(test_data_path): + alert_config_abs_path = join(test_data_path, test_file_path) + + if not isfile(alert_config_abs_path): + continue # skip directories + + if not test_file_path.lower().endswith('.yaml'): + continue # non-yaml files are not intended for being tested + + print(alert_config_abs_path, valid_expected) + + with open(alert_config_abs_path, 'r') as fh: + yaml_content = load(fh) + adjust_tosca_definitions_import(yaml_content) + + valid_real = True + try: + ToscaTemplate(yaml_dict_tpl=yaml_content) + except Exception: + valid_real = False + + assert valid_expected == valid_real, "TOSCA parser test failed for file: {0}".format(alert_config_abs_path) + + def test_alerts_config_clmc_validation(self): + """ + Tests the custom CLMC validation of the TOSCA alerts specification. + """ + + for path_suffix, valid_expected in (("valid", True), ("invalid", False)): + test_data_path = join(ROOT_DIR, *["resources", "tosca", "test-data", "clmc-validator", path_suffix]) + + for test_file_path in listdir(test_data_path): + alert_config_abs_path = join(test_data_path, test_file_path) + + if not isfile(alert_config_abs_path): + continue # skip directories + + if not test_file_path.lower().endswith('.yaml'): + continue # non-yaml files are not intended for being tested + + print(alert_config_abs_path, valid_expected) + + with open(alert_config_abs_path, 'r') as fh: + yaml_content = load(fh) + adjust_tosca_definitions_import(yaml_content) + + # do not catch exceptions here since we are testing the clmc validator, the tosca parsing is tested in the previous test method + alert_tosca_spec = ToscaTemplate(yaml_dict_tpl=yaml_content) + valid_real, err = validate_clmc_alerts_specification(alert_tosca_spec.tpl, include_error=True) + assert valid_expected == valid_real, "CLMC alerts specification validator test failed for file: {0}".format(alert_config_abs_path) + + def test_alerts_config_api_post(self, app_config): + """ + Tests the POST API endpoint of the alerts configuration API responsible for receiving alerts specifications. + + :param app_config: fixture for setUp/tearDown of the web service registry + """ + + pass diff --git a/src/service/clmcservice/alertsapi/utilities.py b/src/service/clmcservice/alertsapi/utilities.py new file mode 100644 index 0000000..ce10967 --- /dev/null +++ b/src/service/clmcservice/alertsapi/utilities.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 +""" +// © University of Southampton IT Innovation Centre, 2018 +// +// Copyright in this software belongs to University of Southampton +// IT Innovation Centre of Gamma House, Enterprise Road, +// Chilworth Science Park, Southampton, SO16 7NS, UK. +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Nikolay Stanchev +// Created Date : 16-08-2018 +// Created for Project : FLAME +""" + + +# Python standard libs +from os.path import join + +# PIP installed libs +from schema import SchemaError + +# CLMC-service imports +from clmcservice import ROOT_DIR +from clmcservice.alertsapi.alerts_specification_schema import ALERTS_SPECIFICATION_SCHEMA + + +CLMC_ALERTS_TOSCA_DEFINITIONS_REL_PATH = ["resources", "tosca", "flame_clmc_alerts_definitions.yaml"] + +CLMC_ALERTS_TOSCA_DEFINITIONS_ABS_PATH = join(ROOT_DIR, *CLMC_ALERTS_TOSCA_DEFINITIONS_REL_PATH) + +CLMC_ALERTS_TOSCA_DEFINITIONS_FILE = CLMC_ALERTS_TOSCA_DEFINITIONS_REL_PATH[-1] + + +def adjust_tosca_definitions_import(alert_spec): + """ + A utility function to adjust any imports of flame_clmc_alerts_definitions.yaml to point to the correct location of + the tosca definitions file. + + :param alert_spec: the TOSCA alert specification content (yaml dict) + """ + + global CLMC_ALERTS_TOSCA_DEFINITIONS_ABS_PATH + + try: + import_index = alert_spec["imports"].index(CLMC_ALERTS_TOSCA_DEFINITIONS_FILE) + alert_spec["imports"][import_index] = CLMC_ALERTS_TOSCA_DEFINITIONS_ABS_PATH + except Exception: + pass # nothing to replace if the import is not specified (either imports are missed, or no reference to the clmc tosca definitions file) + + +def validate_clmc_alerts_specification(tosca_yaml_tpl, include_error=False): + """ + CLMC validation for the TOSCA alerts specification, uses the schema defined in alerts_specification_schema.py + + :param tosca_yaml_tpl: the tosca template to validate (as python dictionary object) + :param include_error: a flag indicating whether the output of the function should include a caught SchemaError + (if set to True and no error is thrown, returns None as the error object) + + :return: True/False if the tosca_tpl is valid/invalid along with any error (None if no error) that was thrown during validation (if argument include_error is set to True) + """ + + try: + ALERTS_SPECIFICATION_SCHEMA.validate(tosca_yaml_tpl) + valid, err = True, None + except SchemaError as e: + valid, err = False, e + + if include_error: + return valid, err + else: + return valid diff --git a/src/service/clmcservice/alertsapi/views.py b/src/service/clmcservice/alertsapi/views.py new file mode 100644 index 0000000..19f67dd --- /dev/null +++ b/src/service/clmcservice/alertsapi/views.py @@ -0,0 +1,139 @@ +#!/usr/bin/python3 +""" +// © University of Southampton IT Innovation Centre, 2018 +// +// Copyright in this software belongs to University of Southampton +// IT Innovation Centre of Gamma House, Enterprise Road, +// Chilworth Science Park, Southampton, SO16 7NS, UK. +// +// This software may not be used, sold, licensed, transferred, copied +// or reproduced in whole or in part in any manner or form or in or +// on any media by any person other than in accordance with the terms +// of the Licence Agreement supplied with the software, or otherwise +// without the prior written consent of the copyright owners. +// +// This software is distributed WITHOUT ANY WARRANTY, without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE, except where stated in the Licence Agreement supplied with +// the software. +// +// Created By : Nikolay Stanchev +// Created Date : 14-08-2018 +// Created for Project : FLAME +""" + +# Python standard libs +import logging + +# PIP installed libs +from pyramid.httpexceptions import HTTPBadRequest +from pyramid.view import view_defaults, view_config +from yaml import load, YAMLError +from toscaparser.tosca_template import ToscaTemplate +from requests import post + +# CLMC-service imports +from clmcservice.alertsapi.utilities import validate_clmc_alerts_specification, adjust_tosca_definitions_import +from clmcservice.alertsapi.alerts_specification_schema import COMPARISON_OPERATORS, fill_threshold_template_vars, fill_http_post_handler_vars + +# initialise logger +log = logging.getLogger('service_logger') + + +@view_defaults(renderer='json') +class AlertsConfigurationAPI(object): + """ + A class-based view for configuring alerts within CLMC. + """ + + def __init__(self, request): + """ + Initialises the instance of the view with the request argument. + + :param request: client's call request + """ + + self.request = request + + @view_config(route_name='alerts_configuration', request_method='POST') + def post_alerts_specification(self): + """ + The view for receiving and configuring alerts based on the TOSCA alerts specification document. + + :raises HTTPBadRequest: if the request doesn't contain a (YAML) file input referenced as alert-spec representing the TOSCA Alerts Specification + """ + + if not hasattr(self.request.POST.get('alert-spec'), "file") or not hasattr(self.request.POST.get('alert-spec'), "filename"): + raise HTTPBadRequest("Request to this API endpoint must include a (YAML) file input referenced as 'alert-spec' representing the TOSCA Alerts Specification.") + + input_filename = self.request.POST['alert-spec'].filename + input_file = self.request.POST['alert-spec'].file + + if not input_filename.lower().endswith('.yaml'): + raise HTTPBadRequest("Request to this API endpoint must include a (YAML) file input referenced as 'alert-spec' representing the TOSCA Alerts Specification.") + + try: + yaml_content = load(input_file) + adjust_tosca_definitions_import(yaml_content) + except YAMLError as err: + log.error("Couldn't parse user request file {0} to yaml format due to error: {1}".format(input_filename, err)) + log.error("Invalid content is: {0}".format(input_file.read())) + raise HTTPBadRequest("Request alert specification file could not be parsed as valid YAML document.") + + try: + tosca_tpl = ToscaTemplate(yaml_dict_tpl=yaml_content) + except Exception as e: + log.error(e) + raise HTTPBadRequest("Request alert specification file could not be parsed as a valid TOSCA document.") + + valid_alert_spec = validate_clmc_alerts_specification(tosca_tpl.tpl) + if not valid_alert_spec: + raise HTTPBadRequest("Request alert specification file could not be validated as a CLMC TOSCA alerts specification document.") + + sfc, sfc_instance = tosca_tpl.tpl["metadata"]["sfc"], tosca_tpl.tpl["metadata"]["sfci"] + db = sfc # ASSUMPTION: database per service function chain, named after the service function chain ID + + for policy in tosca_tpl.policies: + for trigger in policy.triggers: + event_id = trigger.name + event_type = trigger.trigger_tpl["event_type"] + template_id = "{0}_template".format(event_type) + measurement, field = trigger.trigger_tpl["metric"].split(".") + critical_value = float(trigger.trigger_tpl["condition"]["threshold"]) + alert_period = "{0}s".format(trigger.trigger_tpl["condition"]["granularity"]) + influx_function = trigger.trigger_tpl["condition"]["aggregation_method"] + where_clause = None + if "resource_type" in trigger.trigger_tpl["condition"]: + tags = trigger.trigger_tpl["conditon"]["resource_type"] + where_clause = " AND ".join(map(lambda tag_name: "{0}={1}".format(tag_name, tags[tag_name]), tags)) + comparison_operator = COMPARISON_OPERATORS[trigger.trigger_tpl["condition"]["comparison_operator"]] + http_handlers = trigger.trigger_tpl["action"]["implementation"] + topic_id = "{0}___{1}___{2}".format(sfc, sfc_instance, event_id) # scoped per service function chain instance (no two sfc instances report to the same topic) + alert_id = "{0}___{1}".format(policy.name, event_id) + + # create and activate alert task + kapacitor_api_tasks_url = "http://localhost:9092/kapacitor/v1/tasks" + if event_type == "threshold": + kapacitor_http_request_body = { + "id": alert_id, + "template-id": template_id, + "dbrps": [{"db": db, "rp": "autogen"}], + "status": "enabled", + "vars": fill_threshold_template_vars(db, measurement, field, influx_function, critical_value, + comparison_operator, alert_period, topic_id, where_clause=where_clause) + } + + response = post(kapacitor_api_tasks_url, data=kapacitor_http_request_body) + response_content = response.json() + log.info(response_content) + + kapacitor_api_handlers_url = "http://localhost:9092/kapacitor/v1/alerts/topics/{0}/handlers".format(topic_id) + for http_handler_url in http_handlers: + handler_id = "{0}___{1}___{2}".format(policy.name, event_id, http_handler_url) + kapacitor_http_request_body = fill_http_post_handler_vars(handler_id, http_handler_url) + response = post(kapacitor_api_handlers_url, data=kapacitor_http_request_body) + response_content = response.json() + log.info(response_content) + + return {"msg": "Alerts specification has been successfully validated and configured", "service_function_chain_id": sfc, + "service_function_chain_instance_id": sfc_instance} diff --git a/src/service/clmcservice/resources/TICKscript/threshold_template.tick b/src/service/clmcservice/resources/TICKscript/threshold_template.tick new file mode 100644 index 0000000..ed1e646 --- /dev/null +++ b/src/service/clmcservice/resources/TICKscript/threshold_template.tick @@ -0,0 +1,29 @@ +var db string // database per service function chain, so db is named after sfc + +var rp = 'autogen' // default value for the retention policy + +var measurement string + +var field string + +var influxFunction string + +var whereClause = 'TRUE' // default value is TRUE, hence no filtering of the query result + +var messageValue = 'TRUE' // default value is TRUE, as this is what SFEMC expects as a notification for an event rule + +var comparisonLambda lambda + +var alertPeriod duration + +var topicID string + + +batch + |query('SELECT ' + influxFunction + '(' + field + ') AS real_value FROM "' + db + '"."' + rp + '"."' + measurement + '" WHERE ' + whereClause) + .period(alertPeriod) + .every(alertPeriod) + |alert() + .crit(comparisonLambda) + .message(messageValue) + .topic(topicID) diff --git a/src/service/clmcservice/resources/tosca/flame_clmc_alerts_definitions.yaml b/src/service/clmcservice/resources/tosca/flame_clmc_alerts_definitions.yaml new file mode 100644 index 0000000..c49a647 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/flame_clmc_alerts_definitions.yaml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +policy_types: + + eu.ict-flame.policies.StateChange: + + derived_from: tosca.policies.Update + + eu.ict-flame.policies.Alert: + + derived_from: tosca.policies.Root \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-1.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-1.yaml new file mode 100644 index 0000000..b24fd3a --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-1.yaml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + # Fails since policy has no HTTP alert handlers in the implementation. \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-10.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-10.yaml new file mode 100644 index 0000000..ec5de6e --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-10.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc_ID: companyA-VR # correct format is sfc, not sfc_ID + sfci_ID: companyA-VR-premium # correct format is sfci, not sfci_ID + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-2.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-2.yaml new file mode 100644 index 0000000..3ff9985 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-2.yaml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: less than # invalid comparison operator + action: + implementation: + - http://companyA.alert-handler.flame.eu/high-latency \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-3.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-3.yaml new file mode 100644 index 0000000..9d50bca --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-3.yaml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package_id: storage # sf_package_id is not the correct tag name, it is sf_package + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://companyA.alert-handler.flame.eu/high-latency \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-4.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-4.yaml new file mode 100644 index 0000000..3f4f7c1 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-4.yaml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: average # wrong aggregation method - should be mean, not average + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://companyA.alert-handler.flame.eu/high-latency \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-5.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-5.yaml new file mode 100644 index 0000000..ea60be6 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-5.yaml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: mean + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://companyA.alert-handler.flame.eu/high-latency + - sfemc-webhook # should be a valid URL address \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-6.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-6.yaml new file mode 100644 index 0000000..57decbd --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-6.yaml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network-latency # should be in format measurement.field - e.g. network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://companyA.alert-handler.flame.eu/high-latency \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-7.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-7.yaml new file mode 100644 index 0000000..10e47bc --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-7.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold-template # should be one of ("threshold", "relative", "deadman") + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-8.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-8.yaml new file mode 100644 index 0000000..92ca88d --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-8.yaml @@ -0,0 +1,40 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + # should specify at least 1 trigger + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-9.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-9.yaml new file mode 100644 index 0000000..dcb38d1 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/invalid/alerts_test_config-9.yaml @@ -0,0 +1,52 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +# missing metadata section + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-1.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-1.yaml new file mode 100644 index 0000000..46c11df --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-1.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-2.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-2.yaml new file mode 100644 index 0000000..ebf78f0 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-2.yaml @@ -0,0 +1,56 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +# no description, valid since it is optional + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.Alert # Policies of type Alert are also defined + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + sfc: companyA-VR # sfc tag is also allowed, even though it is already included in the metadata + sfci: companyA-VR-premium # sfci tag is also allowed, even though it is already included in the metadata + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-3.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-3.yaml new file mode 100644 index 0000000..ae6471f --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-3.yaml @@ -0,0 +1,52 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +# no description, valid since it is optional + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + # optional description - hence, valid + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: median + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + # optional description - hence, valid + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: first + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-4.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-4.yaml new file mode 100644 index 0000000..5e716e8 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-4.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +# no description, valid since it is optional + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + # optional description - hence, valid + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: median + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + # optional description - hence, valid + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: first + # resource type missing - optional, so it is valid + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-5.yaml b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-5.yaml new file mode 100644 index 0000000..0566801 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/clmc-validator/valid/alerts_test_config-5.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +# no description, valid since it is optional + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + # optional description - hence, valid + event_type: relative # relative template is allowed + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: median + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + # optional description - hence, valid + event_type: deadman # deadman template is allowed + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: first + # resource type missing - optional, so it is valid + comparison_operator: lt + action: + implementation: + - https://sfemc.flame.eu/notify + - http://localhost:9999/low-requests # localhost url is also allowed diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-1.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-1.yaml new file mode 100644 index 0000000..92bac7b --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-1.yaml @@ -0,0 +1,40 @@ +# Fails since it doesn't specify tosca version, imports and topology_template root node is missing. + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium +triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-2.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-2.yaml new file mode 100644 index 0000000..b7e5b8b --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-2.yaml @@ -0,0 +1,53 @@ +# Fails because it's missing tosca version. +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-3.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-3.yaml new file mode 100644 index 0000000..60167c2 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-3.yaml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: +# missing policies section + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-4.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-4.yaml new file mode 100644 index 0000000..1fdc4b3 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/invalid/alerts_test_config-4.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +# Wrong section name, must be topology_template, not alerts +alerts: + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-1.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-1.yaml new file mode 100644 index 0000000..dba2e22 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-1.yaml @@ -0,0 +1,54 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + resource_type: + location: watershed + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-2.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-2.yaml new file mode 100644 index 0000000..4196cf6 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-2.yaml @@ -0,0 +1,48 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VirtualReality + sfci: premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + comparison_operator: lt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-3.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-3.yaml new file mode 100644 index 0000000..118797e --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-3.yaml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - high_latency_policy: + type: eu.ict-flame.policies.StateChange + triggers: + high_latency: + description: This event triggers when the mean network latency in a given location exceeds a given threshold (in ms). + event_type: threshold + metric: network.latency + condition: + threshold: 45 + granularity: 120 + aggregation_method: mean + comparison_operator: gt + action: + implementation: + - http://sfemc.flame.eu/notify + - http://companyA.alert-handler.flame.eu/high-latency diff --git a/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-4.yaml b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-4.yaml new file mode 100644 index 0000000..8e7f188 --- /dev/null +++ b/src/service/clmcservice/resources/tosca/test-data/tosca-parser/valid/alerts_test_config-4.yaml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: TOSCA Alerts Configuration document + +imports: +- flame_clmc_alerts_definitions.yaml + +metadata: + sfc: companyA-VR + sfci: companyA-VR-premium + +topology_template: + + policies: + - low_requests_policy: + type: eu.ict-flame.policies.StateChange + triggers: + low_requests: + description: | + This event triggers when the last reported number of requests for a given service function + falls behind a given threshold. + event_type: threshold + metric: storage.requests + condition: + threshold: 5 + granularity: 60 + aggregation_method: last + resource_type: + sf_package: storage + sf: storage-users + location: watershed + comparison_operator: lt + action: + implementation: + - http://companyA.alert-handler.flame.eu/low-requests \ No newline at end of file diff --git a/src/service/setup.py b/src/service/setup.py index c3fbf0e..c020a6e 100644 --- a/src/service/setup.py +++ b/src/service/setup.py @@ -22,20 +22,31 @@ """ +# Python standard libs import os import os.path from setuptools import setup, find_packages -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() +def get_version(*relative_path): + """ + Reads and parses a version file. + :param relative_path: iterable representing the relative path to the version file, e.g. ["clmcservice", "VERSION"] + :return: + """ + + fname = os.path.join(os.path.dirname(__file__), *relative_path) -def get_version(fname): if os.path.isfile(fname): - git_revision = read(fname) + with open(fname) as f: # Use context managers when opening files, otherwise file handlers might not be properly closed + version = {} + # execute the version file and put its content in the version dictionary + exec(f.read(), version) + # extract the __version__ variable from the dictionary, if not found use default value "SNAPSHOT" + git_revision = version.get("__version__", "SNAPSHOT") else: - git_revision = "SNAPSHOT" + git_revision = "SNAPSHOT" return git_revision @@ -51,7 +62,11 @@ requires = [ 'psycopg2', 'influxdb', 'neo4j-driver', - 'py2neo' + 'py2neo', + 'pyyaml', + 'tosca-parser', + 'schema', + 'requests' ] tests_require = [ @@ -61,7 +76,7 @@ tests_require = [ setup( name="clmcservice", - version=get_version("_version.py"), + version=get_version("clmcservice", "VERSION"), author="Michael Boniface", author_email="mjb@it-innovation.soton.ac.uk", description="FLAME CLMC Service Module", @@ -75,7 +90,6 @@ setup( extras_require={ 'testing': tests_require, }, - package_data={'': ['_version.py']}, classifiers=[ "Development Status :: Alpha", "Topic :: FLAME CLMC Service", diff --git a/src/test/clmctest/alerts/alert_example.tick b/src/test/clmctest/alerts/alert_example.tick deleted file mode 100644 index b218eae..0000000 --- a/src/test/clmctest/alerts/alert_example.tick +++ /dev/null @@ -1,13 +0,0 @@ -dbrp "_internal"."monitor" - -batch - |query(''' - SELECT mean(numSeries) as mean - FROM "_internal"."monitor"."database" - ''') - .period(10s) - .every(10s) - |alert() - .crit(lambda: "mean" > 1) - .message('{"http_topic": "true"}') - .topic('http_topic') \ No newline at end of file diff --git a/src/test/clmctest/alerts/configuration.json b/src/test/clmctest/alerts/configuration.json deleted file mode 100644 index d889e4e..0000000 --- a/src/test/clmctest/alerts/configuration.json +++ /dev/null @@ -1,43 +0,0 @@ -[ - { - "type": "threshold", - "comparison": "greater_than", - "db": "database", - "rp": "retention_policy", - "measurement": "measurement_name", - "field": "field_name", - "period": "50", (read this from TOSCA or default value) - "context": { - "sfc": "sfc_id", - "sfc_instance": "sfc_i_id", - "sf": "sf_node_name", - "sf_endpoint": "sf_endpoint_id" - }, - "threshold_value": <number>, - "event_name": "pub_sub_topic_id", - "http_handlers": [ - "http://handler1.com", - "http://handler2.com" - ] ??? - }, - { - "type": "threshold", - "comparison": "greater_than", - "db": "database", - "rp": "retention_policy", - "measurement": "measurement_name", - "field": "field_name", - "context": { - "sfc": "sfc_id", - "sfc_instance": "sfc_i_id", - "sf": "sf_node_name", - "sf_endpoint": "sf_endpoint_id" - }, - "threshold_value": <number>, - "event_name": "pub_sub_topic_id", - "http_handlers": [ - "http://handler1.com", - "http://handler2.com" - ] - } -] \ No newline at end of file diff --git a/src/test/clmctest/alerts/handler_example.yaml b/src/test/clmctest/alerts/handler_example.yaml deleted file mode 100644 index e6c62d4..0000000 --- a/src/test/clmctest/alerts/handler_example.yaml +++ /dev/null @@ -1,7 +0,0 @@ -id: handler_id -topic: http_topic -kind: post -options: - url: http://localhost:9999/ - headers: - 'Content-Type': 'text/html' \ No newline at end of file diff --git a/src/test/clmctest/alerts/http_server.py b/src/test/clmctest/alerts/http_server.py deleted file mode 100644 index 6a478de..0000000 --- a/src/test/clmctest/alerts/http_server.py +++ /dev/null @@ -1,37 +0,0 @@ -from http.server import HTTPServer, BaseHTTPRequestHandler -import logging - - -logger = logging.getLogger('alerts-test') -logger.setLevel(logging.DEBUG) -fh = logging.FileHandler("/var/log/alert-test.log") -fh.setLevel(logging.DEBUG) -logger.addHandler(fh) - - -class CustomHTTPHandler(BaseHTTPRequestHandler): - - def _set_headers(self): - self.send_response(200) - self.send_header('Content-type', 'text/html') - self.end_headers() - - def do_POST(self): - content_length = int(self.headers['Content-Length']) - post_data = self.rfile.read(content_length) - post_data = post_data.decode(self.headers['Accept-Charset']) - logger.debug(post_data) - - def do_GET(self): - self._set_headers() - self.wfile.write(b"<html><body><h1>SUCCESSFUL GET REQUEST</h1></body></html>") - - -def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler): - server_address = ('localhost', 9999) - httpd = server_class(server_address, handler_class) - httpd.serve_forever() - - -if __name__ == "__main__": - run(handler_class=CustomHTTPHandler) diff --git a/src/test/clmctest/alerts/threshold_configuration.json b/src/test/clmctest/alerts/threshold_configuration.json deleted file mode 100644 index dc20c79..0000000 --- a/src/test/clmctest/alerts/threshold_configuration.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "db": {"type": "string", "value": "_internal"}, - "rp": {"type": "string", "value": "monitor"}, - "measurement": {"type": "string", "value": "database"}, - "field": {"type": "string", "value": "numMeasurements"}, - "criticalValue": {"type": "float", "value": 2.0}, - "topicID": {"type": "string", "value": "dummyAlert"} -} \ No newline at end of file diff --git a/src/test/clmctest/alerts/threshold_template.tick b/src/test/clmctest/alerts/threshold_template.tick deleted file mode 100644 index 5c5658b..0000000 --- a/src/test/clmctest/alerts/threshold_template.tick +++ /dev/null @@ -1,26 +0,0 @@ -var db string - -var rp = 'autogen' // default value for the retention policy - -var measurement string - -var field string - -var whereCondition = 'TRUE' // default value is TRUE, hence no filtering of the query result - -var messageValue = 'TRUE' // default value is TRUE, as this is what SFEMC expects as a notification for an event rule - -var criticalValue float - -var alertPeriod = 60s // this value is read from TOSCA and is measured in seconds, default value is 60 seconds - -var topicID string - -batch - |query('SELECT mean(' + field + ') AS mean_value FROM "' + db + '"."' + rp + '"."' + measurement + '" WHERE ' + whereCondition) - .period(alertPeriod) - .every(alertPeriod) - |alert() - .crit(lambda: "mean_value" >= criticalValue) - .message('{' + topicID + ':' + messageValue + '}') - .topic(topicID) -- GitLab