Fixes bugs regarding alarm deletion 45/6945/4
authorBenjamin Diaz <bdiaz@whitestack.com>
Thu, 22 Nov 2018 20:27:35 +0000 (17:27 -0300)
committerBenjamin Diaz <bdiaz@whitestack.com>
Thu, 22 Nov 2018 20:28:38 +0000 (17:28 -0300)
Adds healthcheck script to be used in devops MON Dockerfile
Removes unused dependencies

Signed-off-by: Benjamin Diaz <bdiaz@whitestack.com>
Change-Id: Ia353c0ae9ee6a502667c04c96f1bc7f3e9337ced

README.rst
debian/python3-osm-mon.postinst
docker/Dockerfile
osm_mon/cmd/mon_healthcheck.py [new file with mode: 0644]
osm_mon/core/database.py
osm_mon/core/models/delete_alarm_resp.json
osm_mon/core/response.py
osm_mon/evaluator/evaluator.py
osm_mon/server/server.py
requirements.txt
setup.py

index 9093b6d..ef34a3d 100644 (file)
@@ -1,66 +1,57 @@
 ..
-       # Copyright 2017 Intel Research and Development Ireland Limited
      # *************************************************************
-       # This file is part of OSM Monitoring module
-       # All Rights Reserved to Intel Corporation
-       #
-       # Licensed under the Apache License, Version 2.0 (the "License"); you may
-       # not use this file except in compliance with the License. You may obtain
-       # a copy of the License at
-       #
-       #         http://www.apache.org/licenses/LICENSE-2.0
-       #
-       # Unless required by applicable law or agreed to in writing, software
-       # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-       # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-       # License for the specific language governing permissions and limitations
-       # under the License.
-       #
      # For those usages not covered by the Apache License, Version 2.0 please
      # contact: prithiv.mohan@intel.com or adrian.hoban@intel.com
+ Copyright 2018 Whitestack, LLC
+ *************************************************************
+
+ This file is part of OSM Monitoring module
+ All Rights Reserved to Whitestack, LLC
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
+ not use this file except in compliance with the License. You may obtain
+ a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations
+ under the License.
+ For those usages not covered by the Apache License, Version 2.0 please
contact: bdiaz@whitestack.com or glavado@whitestack.com
 
 OSM MON Module
 ****************
 
-MON is a monitoring module for OSM. This module leverages the monitoring
-tool of the supported VIMs through MON's native plugin to send and receive
-metrics and alarms for a VNF.
+MON is a monitoring module for OSM.
+It collects metrics from VIMs and VNFs and exports them to a Prometheus TSDB.
+It manages and evaluates alarms based on those metrics.
 
 Components
 **********
 
 MON module has the following components:
 
- - MON Core, which includes Message Bus and Models
- - Plugin drivers for various VIMs
-
-The MON module communication is classified as
-
- - External to MON(requests to MON from SO)
- - Internal to MON(responses to MON from plugins)
+ - MON Central: Handles vim accounts registration and alarms CRUD operations, through messages in the Kafka bus.
+ - MON Collector: Collects metrics from VIMs and VNFs and then exports them to a TSDB. It uses a plugin model both for collectors and for backends.
+ - MON Evaluator: Evaluates alarms and sends notifications through the Kafka bus when they trigger.
 
-Supported Plugins
-******************
 
-Supported VIMs are OpenStack, VMWare, AWS for now. MON can send/receive metrics
-and alarms from the following plugins in this release.
+Supported Collector Plugins
+***************************
 
- - Gnocchi, Aodh (OpenStack)
- - vROps (VMWare)
- - CloudWatch (AWS)
+ - OpenStack: Requires Aodh and Gnocchi to be enabled.
+ - VROPS: TBD
+ - AWS: TBD
 
 Developers
 **********
 
-  - Prithiv Mohan, Intel Research and Development Ltd, Ireland
-  - Helena McGough, Intel Research and Development Ltd, Ireland
-  - Sachin Bhangare, VMWare, India
-  - Wajeeha Hamid, XFlow Research, Pakistan
+  - Benjamín Díaz, Whitestack, Argentina
 
 Maintainers
 ***********
 
- - Adrian Hoban, Intel Research and Development Ltd, Ireland
+ - Gianpietro Lavado, Whitestack, Peru
 
 Contributions
 *************
index f4fabd1..0e517ea 100644 (file)
@@ -1,19 +1,13 @@
 #!/bin/bash
 
 echo "Installing python dependencies via pip..."
-pip3 install kafka-python==1.4.*
+pip3 install kafka-python==1.4.3
 pip3 install requests==2.18.*
 pip3 install cherrypy==14.0.*
 pip3 install jsmin==2.2.*
 pip3 install jsonschema==2.6.*
 pip3 install python-keystoneclient==3.15.*
-pip3 install boto==2.48
-pip3 install python-cloudwatchlogs-logging==0.0.3
-pip3 install py-cloudwatch==0.0.1
-pip3 install pyvcloud==19.1.1
-pip3 install pyopenssl==17.5.*
 pip3 install six==1.11.*
-pip3 install bottle==0.12.*
 pip3 install peewee==3.1.*
 pip3 install pyyaml==3.*
 pip3 install prometheus_client==0.4.*
index e150169..f9f610a 100644 (file)
@@ -52,6 +52,6 @@ ENV OSMMON_COLLECTOR_INTERVAL 30
 ENV OSMMON_EVALUATOR_INTERVAL 30
 ENV OSMMON_PROMETHEUS_URL http://prometheus:9090
 
-EXPOSE 8662 8000
+EXPOSE 8000
 
 CMD /bin/bash mon/docker/scripts/runInstall.sh
diff --git a/osm_mon/cmd/mon_healthcheck.py b/osm_mon/cmd/mon_healthcheck.py
new file mode 100644 (file)
index 0000000..412410b
--- /dev/null
@@ -0,0 +1,85 @@
+# Copyright 2018 Whitestack, LLC
+# *************************************************************
+
+# This file is part of OSM Monitoring module
+# All Rights Reserved to Whitestack, LLC
+
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+
+#         http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: bdiaz@whitestack.com or glavado@whitestack.com
+##
+
+import logging
+import subprocess
+import sys
+import uuid
+
+import requests
+
+from osm_mon.core.message_bus.consumer import Consumer
+
+log = logging.getLogger(__name__)
+
+
+def main():
+    # Check Kafka
+    if not _processes_running():
+        sys.exit(1)
+    if not _is_kafka_ok():
+        sys.exit(1)
+    if not _is_prometheus_exporter_ok():
+        sys.exit(1)
+    sys.exit(0)
+
+
+def _processes_running():
+    def _contains_process(processes, process_name):
+        for row in processes:
+            if process_name in row:
+                return True
+        return False
+    processes_to_check = ['osm-mon-collector', 'osm-mon-evaluator', 'osm-mon-server']
+    ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]
+    processes_running = ps.split('\n')
+    for p in processes_to_check:
+        if not _contains_process(processes_running, p):
+            return False
+    return True
+
+
+def _is_prometheus_exporter_ok():
+    try:
+        r = requests.get('http://localhost:8000')
+        r.raise_for_status()
+        return True
+    except Exception:
+        log.exception("MON Prometheus exporter is not running")
+        return False
+
+
+def _is_kafka_ok():
+    try:
+        common_consumer = Consumer("mon-healthcheck-" + str(uuid.uuid4()))
+        topics = ['alarm_request', 'vim_account']
+        common_consumer.subscribe(topics)
+        common_consumer.poll()
+        common_consumer.close(autocommit=False)
+        return True
+    except Exception:
+        log.exception("MON can not connect to Kafka")
+        return False
+
+
+if __name__ == '__main__':
+    main()
index 56a1275..a41c0fd 100644 (file)
@@ -23,8 +23,9 @@
 ##
 
 import logging
+import uuid
 
-from peewee import CharField, TextField, FloatField, Model
+from peewee import CharField, TextField, FloatField, Model, AutoField
 from playhouse.db_url import connect
 
 from osm_mon.core.settings import Config
@@ -37,6 +38,7 @@ db = connect(cfg.DATABASE)
 
 
 class BaseModel(Model):
+    id = AutoField(primary_key=True)
 
     class Meta:
         database = db
@@ -54,6 +56,7 @@ class VimCredentials(BaseModel):
 
 
 class Alarm(BaseModel):
+    uuid = CharField(unique=True)
     name = CharField()
     severity = CharField()
     threshold = FloatField()
@@ -81,7 +84,7 @@ class DatabaseManager:
         """Saves vim credentials. If a record with same uuid exists, overwrite it."""
         exists = VimCredentials.get_or_none(VimCredentials.uuid == vim_credentials.uuid)
         if exists:
-            vim_credentials.uuid = exists.uuid
+            vim_credentials.id = exists.id
         vim_credentials.save()
         return vim_credentials
 
@@ -94,7 +97,9 @@ class DatabaseManager:
     def save_alarm(self, name, threshold, operation, severity, statistic, metric_name, vdur_name,
                    vnf_member_index, nsr_id) -> Alarm:
         """Saves alarm."""
+        # TODO: Add uuid optional param and check if exists to handle updates (see self.save_credentials)
         alarm = Alarm()
+        alarm.uuid = str(uuid.uuid4())
         alarm.name = name
         alarm.threshold = threshold
         alarm.operation = operation
@@ -107,11 +112,11 @@ class DatabaseManager:
         alarm.save()
         return alarm
 
-    def delete_alarm(self, alarm_id) -> None:
+    def delete_alarm(self, alarm_uuid) -> None:
         alarm = (Alarm.select()
-                 .where(Alarm.alarm_id == alarm_id)
+                 .where(Alarm.uuid == alarm_uuid)
                  .get())
-        alarm.delete()
+        alarm.delete_instance()
 
     def get_vim_type(self, vim_account_id) -> str:
         """Get the vim type that is required by the message."""
index 5b931f2..d6fec9f 100644 (file)
@@ -21,7 +21,7 @@
 {
   "schema_version": { "type": "string" },
   "schema_type": { "type": "string" },
-  "alarm_deletion_response":
+  "alarm_delete_response":
   {
     "correlation_id": { "type": "integer" },
     "alarm_uuid": { "type": "string" },
index 8a864be..7e49a4f 100644 (file)
@@ -83,8 +83,8 @@ class ResponseBuilder(object):
     def delete_alarm_response(self, **kwargs) -> dict:
         """Generate a response for a delete alarm request."""
         delete_alarm_resp = {"schema_version": schema_version,
-                             "schema_type": "alarm_deletion_response",
-                             "alarm_deletion_response": {
+                             "schema_type": "alarm_delete_response",
+                             "alarm_delete_response": {
                                  "correlation_id": kwargs['cor_id'],
                                  "alarm_uuid": kwargs['alarm_id'],
                                  "status": kwargs['status']}}
index 7613e0b..9591946 100644 (file)
@@ -157,7 +157,7 @@ class Evaluator:
         # Generate and send response
         resp_message = response.generate_response(
             'notify_alarm',
-            alarm_id=alarm.id,
+            alarm_id=alarm.uuid,
             vdu_name=alarm.vdur_name,
             vnf_member_index=alarm.vnf_member_index,
             ns_id=alarm.nsr_id,
index 89ba4e8..854d926 100755 (executable)
@@ -1,22 +1,25 @@
-# Copyright 2017 Intel Research and Development Ireland Limited
+# -*- coding: utf-8 -*-
+
+# Copyright 2018 Whitestack, LLC
 # *************************************************************
+
 # This file is part of OSM Monitoring module
-# All Rights Reserved to Intel Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you
-# may not use this file except in compliance with the License. You may
-# obtain a copy of the License at
-#
+# All Rights Reserved to Whitestack, LLC
+
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+
 #         http://www.apache.org/licenses/LICENSE-2.0
-#
+
 # Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-#
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
 # For those usages not covered by the Apache License, Version 2.0 please
-# contact: helena.mcgough@intel.com or adrian.hoban@intel.com
+# contact: bdiaz@whitestack.com or glavado@whitestack.com
+##
 """A common KafkaConsumer for all MON plugins."""
 
 import json
@@ -91,7 +94,7 @@ class Server:
                         response = response_builder.generate_response('create_alarm_response',
                                                                       cor_id=alarm_details['correlation_id'],
                                                                       status=True,
-                                                                      alarm_id=alarm.id)
+                                                                      alarm_id=alarm.uuid)
                     except Exception:
                         log.exception("Error creating alarm: ")
                         response = response_builder.generate_response('create_alarm_response',
@@ -100,18 +103,18 @@ class Server:
                                                                       alarm_id=None)
                 if message.key == "delete_alarm_request":
                     alarm_details = values['alarm_delete_request']
-                    response_builder = ResponseBuilder()
                     alarm_uuid = alarm_details['alarm_uuid']
+                    response_builder = ResponseBuilder()
                     cor_id = alarm_details['correlation_id']
                     try:
                         self.database_manager.delete_alarm(alarm_uuid)
-                        response = response_builder.generate_response('create_alarm_response',
+                        response = response_builder.generate_response('delete_alarm_response',
                                                                       cor_id=cor_id,
                                                                       status=True,
                                                                       alarm_id=alarm_uuid)
                     except Exception:
-                        log.exception("Error creating alarm: ")
-                        response = response_builder.generate_response('create_alarm_response',
+                        log.exception("Error deleting alarm: ")
+                        response = response_builder.generate_response('delete_alarm_response',
                                                                       cor_id=cor_id,
                                                                       status=False,
                                                                       alarm_id=alarm_uuid)
index e0dba98..10562f2 100644 (file)
 
 # For those usages not covered by the Apache License, Version 2.0 please
 # contact: prithiv.mohan@intel.com or adrian.hoban@intel.com
-kafka-python==1.4.*
+kafka-python==1.4.3
 requests==2.18.*
 cherrypy==14.0.*
 jsmin==2.2.*
 jsonschema==2.6.*
 python-keystoneclient==3.15.*
-boto==2.48
-python-cloudwatchlogs-logging==0.0.3
-py-cloudwatch==0.0.1
-pyvcloud==19.1.1
-pyopenssl==17.5.*
 six==1.11.*
-bottle==0.12.*
 peewee==3.1.*
 pyyaml==3.*
 prometheus_client==0.4.*
index a5f0ca5..c85fa76 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -41,7 +41,7 @@ setup(
     name=_name,
     version_command=_version_command,
     description=_description,
-    long_description=open('README.rst').read(),
+    long_description=open('README.rst', encoding='utf-8').read(),
     author=_author,
     author_email=_author_email,
     maintainer=_maintainer,
@@ -51,19 +51,13 @@ setup(
     packages=[_name],
     package_dir={_name: _name},
     install_requires=[
-        "kafka-python==1.4.*",
+        "kafka-python==1.4.3",
         "requests==2.18.*",
         "cherrypy==14.0.*",
         "jsmin==2.2.*",
         "jsonschema==2.6.*",
         "python-keystoneclient==3.15.*",
-        "boto==2.48",
-        "python-cloudwatchlogs-logging==0.0.3",
-        "py-cloudwatch==0.0.1",
-        "pyvcloud==19.1.1",
-        "pyopenssl==17.5.*",
         "six==1.11.*",
-        "bottle==0.12.*",
         "peewee==3.1.*",
         "pyyaml==3.*",
         "prometheus_client==0.4.*",
@@ -77,6 +71,7 @@ setup(
             "osm-mon-server = osm_mon.cmd.mon_server:main",
             "osm-mon-evaluator = osm_mon.cmd.mon_evaluator:main",
             "osm-mon-collector = osm_mon.cmd.mon_collector:main",
+            "osm-mon-healthcheck = osm_mon.cmd.mon_healthcheck:main",
         ]
     },
     dependency_links=[