Refactored the Aodh notifier class
[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
27 import logging
28
29 import sys
30
31 import time
32
33 from BaseHTTPServer import BaseHTTPRequestHandler
34 from BaseHTTPServer import HTTPServer
35
36 # Initialise a logger for alarm notifier
37 logging.basicConfig(filename='aodh_notify.log',
38 format='%(asctime)s %(message)s',
39 datefmt='%m/%d/%Y %I:%M:%S %p', filemode='a',
40 level=logging.INFO)
41 log = logging.getLogger(__name__)
42
43 sys.path.append("/root/MON")
44
45 from core.message_bus.producer import KafkaProducer
46
47 from plugins.OpenStack.Aodh.alarming import Alarming
48 from plugins.OpenStack.common import Common
49 from plugins.OpenStack.response import OpenStack_Response
50 from plugins.OpenStack.settings import Config
51
52
53 class NotifierHandler(BaseHTTPRequestHandler):
54 """Handler class for alarm_actions triggered by OSM alarms."""
55
56 def _set_headers(self):
57 """Set the headers for a request."""
58 self.send_response(200)
59 self.send_header('Content-type', 'text/html')
60 self.end_headers()
61
62 def do_GET(self):
63 """Get request functionality."""
64 self._set_headers()
65 self.wfile.write("<html><body><h1>hi!</h1></body></html>")
66
67 def do_POST(self):
68 """POST request function."""
69 # Gets header and data from the post request and records info
70 self._set_headers()
71 # Gets the size of data
72 content_length = int(self.headers['Content-Length'])
73 post_data = self.rfile.read(content_length)
74 self.wfile.write("<html><body><h1>POST!</h1></body></tml>")
75 log.info("This alarm was triggered: %s", json.loads(post_data))
76
77 # Generate a notify_alarm response for the SO
78 self.notify_alarm(json.loads(post_data))
79
80 def notify_alarm(self, values):
81 """Send a notifcation repsonse message to the SO."""
82 # Initialiase configuration and authentication for response message
83 config = Config.instance()
84 config.read_environ("aodh")
85 self._alarming = Alarming()
86 self._common = Common()
87 self._response = OpenStack_Response()
88 self._producer = KafkaProducer('alarm_response')
89
90 alarm_id = values['alarm_id']
91 auth_token = self._common._authenticate()
92 endpoint = self._common.get_endpoint("alarming")
93
94 # If authenticated generate and send response message
95 if (auth_token is not None and endpoint is not None):
96 url = "{}/v2/alarms/%s".format(endpoint) % alarm_id
97
98 # Get the resource_id of the triggered alarm
99 result = self._common._perform_request(
100 url, auth_token, req_type="get")
101 alarm_details = json.loads(result.text)
102 gnocchi_rule = alarm_details['gnocchi_resources_threshold_rule']
103 resource_id = gnocchi_rule['resource_id']
104
105 # Process an alarm notification if resource_id is valid
106 if resource_id is not None:
107 # Get date and time for response message
108 a_date = time.strftime("%d-%m-%Y") + " " + time.strftime("%X")
109 # Try generate and send response
110 try:
111 resp_message = self._response.generate_response(
112 'notify_alarm', a_id=alarm_id,
113 r_id=resource_id,
114 sev=values['severity'], date=a_date,
115 state=values['current'], vim_type="OpenStack")
116 self._producer.notify_alarm(
117 'notify_alarm', resp_message, 'alarm_response')
118 log.info("Sent an alarm response to SO: %s", resp_message)
119 except Exception as exc:
120 log.warn("Couldn't notify SO of the alarm: %s", exc)
121 else:
122 log.warn("No resource_id for alarm; no SO response sent.")
123 else:
124 log.warn("Authentication failure; SO notification not sent.")
125
126
127 def run(server_class=HTTPServer, handler_class=NotifierHandler, port=8662):
128 """Run the webserver application to retreive alarm notifications."""
129 try:
130 server_address = ('', port)
131 httpd = server_class(server_address, handler_class)
132 print('Starting alarm notifier...')
133 log.info("Starting alarm notifier server on port: %s", port)
134 httpd.serve_forever()
135 except Exception as exc:
136 log.warn("Failed to start webserver, %s", exc)
137
138 if __name__ == "__main__":
139 from sys import argv
140
141 # Runs the webserver
142 if len(argv) == 2:
143 run(port=int(argv[1]))
144 else:
145 run()