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