a1c85e61f4b49e45bd1e9ba626f6ef0ae30ab47c
[osm/MON.git] / osm_mon / plugins / OpenStack / Aodh / notifier.py
1 # Copyright 2017 Intel Research and Development Ireland Limited
2 # *************************************************************
3
4 # This file is part of OSM Monitoring module
5 # All Rights Reserved to Intel Corporation
6
7 # Licensed under the Apache License, Version 2.0 (the "License"); you may
8 # not use this file except in compliance with the License. You may obtain
9 # a copy of the License at
10
11 # http://www.apache.org/licenses/LICENSE-2.0
12
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 # License for the specific language governing permissions and limitations
17 # under the License.
18
19 # For those usages not covered by the Apache License, Version 2.0 please
20 # contact: helena.mcgough@intel.com or adrian.hoban@intel.com
21 ##
22 # __author__ = Helena McGough
23 #
24 """A Webserver to send alarm notifications from Aodh to the SO."""
25 import json
26 import logging
27 import os
28 import sys
29 import time
30
31 from six.moves.BaseHTTPServer import BaseHTTPRequestHandler
32 from six.moves.BaseHTTPServer import HTTPServer
33
34 # Initialise a logger for alarm notifier
35 from osm_mon.core.message_bus.producer import Producer
36 from osm_mon.core.settings import Config
37
38 cfg = Config.instance()
39
40 logging.basicConfig(stream=sys.stdout,
41 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
42 datefmt='%m/%d/%Y %I:%M:%S %p',
43 level=logging.getLevelName(cfg.OSMMON_LOG_LEVEL))
44 log = logging.getLogger(__name__)
45
46 kafka_logger = logging.getLogger('kafka')
47 kafka_logger.setLevel(logging.getLevelName(cfg.OSMMON_KAFKA_LOG_LEVEL))
48 kafka_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
49 kafka_handler = logging.StreamHandler(sys.stdout)
50 kafka_handler.setFormatter(kafka_formatter)
51 kafka_logger.addHandler(kafka_handler)
52
53 sys.path.append(os.path.abspath(os.path.join(os.path.realpath(__file__), '..', '..', '..', '..', '..')))
54
55 from osm_mon.core.database import DatabaseManager
56
57 from osm_mon.plugins.OpenStack.response import OpenStackResponseBuilder
58
59
60 class NotifierHandler(BaseHTTPRequestHandler):
61 """Handler class for alarm_actions triggered by OSM alarms."""
62
63 def _set_headers(self):
64 """Set the headers for a request."""
65 self.send_response(200)
66 self.send_header('Content-type', 'text/html')
67 self.end_headers()
68
69 def do_GET(self):
70 """Get request functionality."""
71 self._set_headers()
72
73 def do_POST(self):
74 """POST request function."""
75 # Gets header and data from the post request and records info
76 self._set_headers()
77 # Gets the size of data
78 content_length = int(self.headers['Content-Length'])
79 post_data = self.rfile.read(content_length)
80 # Python 2/3 string compatibility
81 try:
82 post_data = post_data.decode()
83 except AttributeError:
84 pass
85 log.info("This alarm was triggered: %s", post_data)
86
87 # Send alarm notification to message bus
88 try:
89 self.notify_alarm(json.loads(post_data))
90 except Exception:
91 log.exception("Error notifying alarm")
92
93 def notify_alarm(self, values):
94 """Sends alarm notification message to bus."""
95
96 # Initialise configuration and authentication for response message
97 response = OpenStackResponseBuilder()
98
99 database_manager = DatabaseManager()
100
101 alarm_id = values['alarm_id']
102 alarm = database_manager.get_alarm(alarm_id, 'openstack')
103 # Process an alarm notification if resource_id is valid
104 # Get date and time for response message
105 a_date = time.strftime("%d-%m-%Y") + " " + time.strftime("%X")
106 # Generate and send response
107 resp_message = response.generate_response(
108 'notify_alarm',
109 alarm_id=alarm_id,
110 vdu_name=alarm.vdu_name,
111 vnf_member_index=alarm.vnf_member_index,
112 ns_id=alarm.ns_id,
113 metric_name=alarm.metric_name,
114 operation=alarm.operation,
115 threshold_value=alarm.threshold,
116 sev=values['severity'],
117 date=a_date,
118 state=values['current'])
119 self._publish_response('notify_alarm', json.dumps(resp_message))
120 log.info("Sent alarm notification: %s", resp_message)
121
122 def _publish_response(self, key: str, msg: str):
123 producer = Producer()
124 producer.send(topic='alarm_response', key=key, value=msg)
125 producer.flush()
126
127
128 def run(server_class=HTTPServer, handler_class=NotifierHandler, port=8662):
129 """Run the webserver application to retrieve alarm notifications."""
130 try:
131 server_address = ('', port)
132 httpd = server_class(server_address, handler_class)
133 print('Starting alarm notifier...')
134 log.info("Starting alarm notifier server on port: %s", port)
135 httpd.serve_forever()
136 except Exception as exc:
137 log.warning("Failed to start webserver, %s", exc)
138
139
140 if __name__ == "__main__":
141 from sys import argv
142
143 # Runs the webserver
144 if len(argv) == 2:
145 run(port=int(argv[1]))
146 else:
147 run()