Adds vdu_id to message bus models
[osm/MON.git] / osm_mon / plugins / OpenStack / Aodh / alarming.py
index 156a0f1..2c145ee 100644 (file)
@@ -25,12 +25,14 @@ import json
 import logging
 
 import six
+import yaml
 
+from osm_mon.core.auth import AuthManager
 from osm_mon.core.database import DatabaseManager
 from osm_mon.core.message_bus.producer import KafkaProducer
+from osm_mon.core.settings import Config
 from osm_mon.plugins.OpenStack.common import Common
 from osm_mon.plugins.OpenStack.response import OpenStack_Response
-from osm_mon.plugins.OpenStack.settings import Config
 
 log = logging.getLogger(__name__)
 
@@ -82,6 +84,7 @@ class Alarming(object):
         config.read_environ()
 
         self._database_manager = DatabaseManager()
+        self._auth_manager = AuthManager()
 
         # Use the Response class to generate valid json response messages
         self._response = OpenStack_Response()
@@ -89,9 +92,46 @@ class Alarming(object):
         # Initializer a producer to send responses back to SO
         self._producer = KafkaProducer("alarm_response")
 
+    def configure_alarm(self, alarm_endpoint, metric_endpoint, auth_token, values, vim_config):
+        """Create requested alarm in Aodh."""
+        url = "{}/v2/alarms/".format(alarm_endpoint)
+
+        # Check if the desired alarm is supported
+        alarm_name = values['alarm_name'].lower()
+        metric_name = values['metric_name'].lower()
+        resource_id = values['resource_uuid']
+
+        if metric_name not in METRIC_MAPPINGS.keys():
+            log.warning("This metric is not supported.")
+            return None, False
+
+        # Check for the required metric
+        metric_id = self.check_for_metric(auth_token, metric_endpoint, metric_name, resource_id)
+
+        try:
+            if metric_id is not None:
+                # Create the alarm if metric is available
+                if 'granularity' in vim_config and 'granularity' not in values:
+                    values['granularity'] = vim_config['granularity']
+                payload = self.check_payload(values, metric_name, resource_id,
+                                             alarm_name)
+                new_alarm = Common.perform_request(
+                    url, auth_token, req_type="post", payload=payload)
+                return json.loads(new_alarm.text)['alarm_id'], True
+            else:
+                log.warning("The required Gnocchi metric does not exist.")
+                return None, False
+
+        except Exception as exc:
+            log.warning("Failed to create the alarm: %s", exc)
+        return None, False
+
     def alarming(self, message):
         """Consume info from the message bus to manage alarms."""
-        values = json.loads(message.value)
+        try:
+            values = json.loads(message.value)
+        except ValueError:
+            values = yaml.safe_load(message.value)
 
         log.info("OpenStack alarm action required.")
         vim_uuid = values['vim_uuid']
@@ -101,12 +141,15 @@ class Alarming(object):
         alarm_endpoint = Common.get_endpoint("alarming", vim_uuid)
         metric_endpoint = Common.get_endpoint("metric", vim_uuid)
 
+        vim_account = self._auth_manager.get_credentials(vim_uuid)
+        vim_config = json.loads(vim_account.config)
+
         if message.key == "create_alarm_request":
             # Configure/Update an alarm
             alarm_details = values['alarm_create_request']
 
             alarm_id, alarm_status = self.configure_alarm(
-                alarm_endpoint, metric_endpoint, auth_token, alarm_details)
+                alarm_endpoint, metric_endpoint, auth_token, alarm_details, vim_config)
 
             # Generate a valid response message, send via producer
             try:
@@ -120,9 +163,8 @@ class Alarming(object):
                     cor_id=alarm_details['correlation_id'])
                 log.info("Response Message: %s", resp_message)
                 self._producer.create_alarm_response(
-                    'create_alarm_response', resp_message,
-                    'alarm_response')
-            except Exception as exc:
+                    'create_alarm_response', resp_message)
+            except Exception:
                 log.exception("Response creation failed:")
 
         elif message.key == "list_alarm_request":
@@ -140,9 +182,8 @@ class Alarming(object):
                     cor_id=list_details['correlation_id'])
                 log.info("Response Message: %s", resp_message)
                 self._producer.list_alarm_response(
-                    'list_alarm_response', resp_message,
-                    'alarm_response')
-            except Exception as exc:
+                    'list_alarm_response', resp_message)
+            except Exception:
                 log.exception("Failed to send a valid response back.")
 
         elif message.key == "delete_alarm_request":
@@ -160,10 +201,9 @@ class Alarming(object):
                     cor_id=request_details['correlation_id'])
                 log.info("Response message: %s", resp_message)
                 self._producer.delete_alarm_response(
-                    'delete_alarm_response', resp_message,
-                    'alarm_response')
-            except Exception as exc:
-                log.warn("Failed to create delete response:%s", exc)
+                    'delete_alarm_response', resp_message)
+            except Exception:
+                log.exception("Failed to create delete response: ")
 
         elif message.key == "acknowledge_alarm":
             # Acknowledge that an alarm has been dealt with by the SO
@@ -176,14 +216,14 @@ class Alarming(object):
             if response is True:
                 log.info("Acknowledged the alarm and cleared it.")
             else:
-                log.warn("Failed to acknowledge/clear the alarm.")
+                log.warning("Failed to acknowledge/clear the alarm.")
 
         elif message.key == "update_alarm_request":
             # Update alarm configurations
             alarm_details = values['alarm_update_request']
 
             alarm_id, status = self.update_alarm(
-                alarm_endpoint, auth_token, alarm_details)
+                alarm_endpoint, auth_token, alarm_details, vim_config)
 
             # Generate a response for an update request
             try:
@@ -193,48 +233,15 @@ class Alarming(object):
                     status=status)
                 log.info("Response message: %s", resp_message)
                 self._producer.update_alarm_response(
-                    'update_alarm_response', resp_message,
-                    'alarm_response')
-            except Exception as exc:
-                log.warn("Failed to send an update response:%s", exc)
+                    'update_alarm_response', resp_message)
+            except Exception:
+                log.exception("Failed to send an update response: ")
 
         else:
             log.debug("Unknown key, no action will be performed")
 
         return
 
-    def configure_alarm(self, alarm_endpoint, metric_endpoint, auth_token, values):
-        """Create requested alarm in Aodh."""
-        url = "{}/v2/alarms/".format(alarm_endpoint)
-
-        # Check if the desired alarm is supported
-        alarm_name = values['alarm_name'].lower()
-        metric_name = values['metric_name'].lower()
-        resource_id = values['resource_uuid']
-
-        if metric_name not in METRIC_MAPPINGS.keys():
-            log.warn("This metric is not supported.")
-            return None, False
-
-        # Check for the required metric
-        metric_id = self.check_for_metric(auth_token, metric_endpoint, metric_name, resource_id)
-
-        try:
-            if metric_id is not None:
-                # Create the alarm if metric is available
-                payload = self.check_payload(values, metric_name, resource_id,
-                                             alarm_name)
-                new_alarm = Common.perform_request(
-                    url, auth_token, req_type="post", payload=payload)
-                return json.loads(new_alarm.text)['alarm_id'], True
-            else:
-                log.warn("The required Gnocchi metric does not exist.")
-                return None, False
-
-        except Exception as exc:
-            log.warn("Failed to create the alarm: %s", exc)
-        return None, False
-
     def delete_alarm(self, endpoint, auth_token, alarm_id):
         """Delete alarm function."""
         url = "{}/v2/alarms/%s".format(endpoint) % alarm_id
@@ -249,8 +256,8 @@ class Alarming(object):
             else:
                 return True
 
-        except Exception as exc:
-            log.warn("Failed to delete alarm: %s because %s.", alarm_id, exc)
+        except Exception:
+            log.exception("Failed to delete alarm %s :", alarm_id)
         return False
 
     def list_alarms(self, endpoint, auth_token, list_details):
@@ -263,14 +270,14 @@ class Alarming(object):
         try:
             resource = list_details['resource_uuid']
         except KeyError as exc:
-            log.warn("Resource id not specified for list request: %s", exc)
+            log.warning("Resource id not specified for list request: %s", exc)
             return None
 
         # Checking what fields are specified for a list request
         try:
             name = list_details['alarm_name'].lower()
             if name not in ALARM_NAMES.keys():
-                log.warn("This alarm is not supported, won't be used!")
+                log.warning("This alarm is not supported, won't be used!")
                 name = None
         except KeyError as exc:
             log.info("Alarm name isn't specified.")
@@ -343,11 +350,11 @@ class Alarming(object):
             Common.perform_request(
                 url, auth_token, req_type="put", payload=payload)
             return True
-        except Exception as exc:
-            log.warn("Unable to update alarm state: %s", exc)
+        except Exception:
+            log.exception("Unable to update alarm state: ")
         return False
 
-    def update_alarm(self, endpoint, auth_token, values):
+    def update_alarm(self, endpoint, auth_token, values, vim_config):
         """Get alarm name for an alarm configuration update."""
         # Get already existing alarm details
         url = "{}/v2/alarms/%s".format(endpoint) % values['alarm_uuid']
@@ -362,11 +369,13 @@ class Alarming(object):
             resource_id = rule['resource_id']
             metric_name = [key for key, value in six.iteritems(METRIC_MAPPINGS) if value == rule['metric']][0]
         except Exception as exc:
-            log.warn("Failed to retrieve existing alarm info: %s.\
+            log.warning("Failed to retrieve existing alarm info: %s.\
                      Can only update OSM alarms.", exc)
             return None, False
 
         # Generates and check payload configuration for alarm update
+        if 'granularity' in vim_config and 'granularity' not in values:
+            values['granularity'] = vim_config['granularity']
         payload = self.check_payload(values, metric_name, resource_id,
                                      alarm_name, alarm_state=alarm_state)
 
@@ -378,7 +387,7 @@ class Alarming(object):
 
                 return json.loads(update_alarm.text)['alarm_id'], True
             except Exception as exc:
-                log.warn("Alarm update could not be performed: %s", exc)
+                log.warning("Alarm update could not be performed: %s", exc)
                 return None, False
         return None, False
 
@@ -400,7 +409,7 @@ class Alarming(object):
 
             statistic = values['statistic'].lower()
 
-            granularity = '300'
+            granularity = cfg.OS_DEFAULT_GRANULARITY
             if 'granularity' in values:
                 granularity = values['granularity']
 
@@ -426,7 +435,7 @@ class Alarming(object):
                                   'alarm_actions': [cfg.OS_NOTIFIER_URI], })
             return payload
         except KeyError as exc:
-            log.warn("Alarm is not configured correctly: %s", exc)
+            log.warning("Alarm is not configured correctly: %s", exc)
         return None
 
     def get_alarm_state(self, endpoint, auth_token, alarm_id):
@@ -438,7 +447,7 @@ class Alarming(object):
                 url, auth_token, req_type="get")
             return json.loads(alarm_state.text)
         except Exception as exc:
-            log.warn("Failed to get the state of the alarm:%s", exc)
+            log.warning("Failed to get the state of the alarm:%s", exc)
         return None
 
     def check_for_metric(self, auth_token, metric_endpoint, m_name, r_id):