fix sensu check handling for link checks 01/41301/2
authoryayogev <yaronyogev@gmail.com>
Thu, 7 Sep 2017 12:14:03 +0000 (15:14 +0300)
committeryayogev <yaronyogev@gmail.com>
Thu, 7 Sep 2017 12:34:21 +0000 (15:34 +0300)
Change-Id: I481d68d90708af194e58f213f1f4c070da76ebc1
Signed-off-by: yayogev <yaronyogev@gmail.com>
app/monitoring/handlers/monitor.py
app/monitoring/handlers/monitoring_check_handler.py

index 95ea4aa..9caed74 100755 (executable)
@@ -26,7 +26,6 @@ class Monitor:
         'inventory': 'inventory',
         'loglevel': 'WARNING'
     }
-    object_types = []
 
     def __init__(self):
         self.args = self.get_args()
@@ -60,34 +59,48 @@ class Monitor:
         args = parser.parse_args()
         return args
 
-    def get_object_types(self) -> list:
-        if not self.object_types:
-            docs = self.inv.find_items({'name': 'object_types'},
-                                       collection='constants')
-            for types_list in docs:
-                self.object_types = [t['value'] for t in types_list['data']]
-        if not self.object_types:
-            raise ValueError('Unable to fetch object types')
-        return self.object_types
+    def get_type_list(self, type_name) -> list:
+        types_list = []
+        docs = self.inv.find_items({'name': type_name}, collection='constants')
+        for types_list in docs:
+            types_list = [t['value'] for t in types_list['data']]
+        if not types_list:
+            raise ValueError('Unable to fetch {}'
+                             .format(type_name.replace('_', ' ')))
+        return types_list
 
     def match_object_types(self, check_name: str) -> list:
-        object_types = self.get_object_types()
+        object_types = self.get_type_list('object_types')
         matches = [t for t in object_types if check_name.startswith(t + '_')]
         return matches
 
+    def match_link_types(self, check_name: str) -> list:
+        object_types = self.get_type_list('link_types')
+        matches = [t for t in object_types
+                   if check_name.startswith('link_' + t + '_')]
+        return matches
+
     def find_object_type_and_id(self, check_name: str):
         # if we have multiple matching host types, then take the longest
         # of these. For example, if matches are ['host', 'host_pnic'],
         # then take 'host_pnic'.
         # To facilitate this, we sort the matches by reverse order.
-        matching_object_types = sorted(self.match_object_types(check_name),
-                                       reverse=True)
-        if not matching_object_types:
-            raise ValueError('Unable to match check name "{}" with object type'
-                             .format(check_name))
-        obj_type = matching_object_types[0]
-        obj_id = check_name[len(obj_type)+1:]
-        return obj_type, obj_id
+        is_link_check = check_name.startswith('link_')
+        check_type = 'link' if is_link_check else 'object'
+        if is_link_check:
+            matching_types = sorted(self.match_link_types(check_name),
+                                    reverse=True)
+        else:
+            matching_types = sorted(self.match_object_types(check_name),
+                                    reverse=True)
+        if not matching_types:
+            raise ValueError('Unable to match check name "{}" with {} type'
+                             .format(check_name, check_type))
+        obj_type = matching_types[0]
+        postfix_len = len('link_') if is_link_check else 0
+        obj_id = (obj_type + '_' if is_link_check else '') + \
+            check_name[len(obj_type)+1+postfix_len:]
+        return check_type, obj_type, obj_id
 
     def read_input(self):
         if self.args.inputfile:
@@ -102,18 +115,19 @@ class Monitor:
             if not self.input_text:
                 raise ValueError("No input provided on stdin")
 
-    def get_handler_by_type(self, obj_type):
-        module_name = 'handle_' + obj_type
+    def get_handler_by_type(self, check_type, obj_type):
+        module_name = 'handle_link' if check_type == 'link' \
+                else 'handle_' + obj_type
         package = 'monitoring.handlers'
         handler = ClassResolver.get_instance_single_arg(self.args,
                                                         module_name=module_name,
                                                         package_name=package)
         return handler
 
-    def get_handler(self, obj_type):
+    def get_handler(self, check_type, obj_type):
         basic_handling_types = ['vedge', 'vservice']
         if obj_type not in basic_handling_types:
-            return self.get_handler_by_type(obj_type)
+            return self.get_handler_by_type(check_type, obj_type)
         from monitoring.handlers.basic_check_handler \
             import BasicCheckHandler
         return BasicCheckHandler(self.args)
@@ -124,11 +138,12 @@ class Monitor:
         check_result = check_result_full['check']
         check_result['id'] = check_result_full['id']
         name = check_result['name']
-        object_type, object_id = monitor.find_object_type_and_id(name)
+        check_type, object_type, object_id = \
+            monitor.find_object_type_and_id(name)
         if 'environment' in check_client:
             self.args.env = check_client['environment']
 
-        check_handler = self.get_handler(object_type)
+        check_handler = self.get_handler(check_type, object_type)
         if check_handler:
             check_handler.handle(object_id, check_result)
 
index ef14c54..a299076 100644 (file)
@@ -78,16 +78,20 @@ class MonitoringCheckHandler(SpecialCharConverter):
         self.keep_message(doc, check_result)
 
     def keep_message(self, doc, check_result, error_level=None):
+        is_link = 'link_type' in doc
         msg_id = check_result['id']
-        obj_id = doc['id']
-        display_context = doc['network_id'] if doc['type'] == 'port'\
+        obj_id = 'link_{}_{}'.format(doc['source_id'], doc['target_id']) \
+            if is_link \
             else doc['id']
+        obj_type = 'link_{}'.format(doc['link_type']) if is_link else doc['type']
+        display_context = obj_id if is_link \
+            else doc['network_id'] if doc['type'] == 'port' else doc['id']
         level = error_level if error_level\
             else ERROR_LEVEL[check_result['status']]
         dt = datetime.datetime.utcfromtimestamp(check_result['executed'])
         ts = stringify_datetime(dt)
         message = Message(msg_id=msg_id, env=self.env, source=SOURCE_SYSTEM,
-                          object_id=obj_id, object_type=doc['type'],
+                          object_id=obj_id, object_type=obj_type,
                           display_context=display_context, level=level,
                           msg=check_result, ts=ts)
         collection = self.inv.collections['messages']