Adds granularity support in OpenStack vim config
[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 self.wfile.write("<html><body><h1>POST!</h1></body></tml>")
74 log.info("This alarm was triggered: %s", json.loads(post_data))
75
76 # Generate a notify_alarm response for the SO
77 self.notify_alarm(json.loads(post_data))
78
79 def notify_alarm(self, values):
80 """Send a notification response message to the SO."""
81
82 try:
83 # Initialise configuration and authentication for response message
84 config = Config.instance()
85 config.read_environ()
86 response = OpenStack_Response()
87 producer = KafkaProducer('alarm_response')
88
89 database_manager = DatabaseManager()
90
91 alarm_id = values['alarm_id']
92 # Get vim_uuid associated to alarm
93 creds = database_manager.get_credentials_for_alarm_id(alarm_id, 'openstack')
94 auth_token = Common.get_auth_token(creds.uuid)
95 endpoint = Common.get_endpoint("alarming", creds.uuid)
96
97 # If authenticated generate and send response message
98 if auth_token is not None and endpoint is not None:
99 url = "{}/v2/alarms/%s".format(endpoint) % alarm_id
100
101 # Get the resource_id of the triggered alarm
102 result = Common.perform_request(
103 url, auth_token, req_type="get")
104 alarm_details = json.loads(result.text)
105 gnocchi_rule = alarm_details['gnocchi_resources_threshold_rule']
106 resource_id = gnocchi_rule['resource_id']
107
108 # Process an alarm notification if resource_id is valid
109 if resource_id is not None:
110 # Get date and time for response message
111 a_date = time.strftime("%d-%m-%Y") + " " + time.strftime("%X")
112 # Try generate and send response
113 try:
114 resp_message = response.generate_response(
115 'notify_alarm', a_id=alarm_id,
116 r_id=resource_id,
117 sev=values['severity'], date=a_date,
118 state=values['current'], vim_type="openstack")
119 producer.notify_alarm(
120 'notify_alarm', resp_message, 'alarm_response')
121 log.info("Sent an alarm response to SO: %s", resp_message)
122 except Exception as exc:
123 log.exception("Couldn't notify SO of the alarm:")
124 else:
125 log.warn("No resource_id for alarm; no SO response sent.")
126 else:
127 log.warn("Authentication failure; SO notification not sent.")
128 except:
129 log.exception("Could not notify alarm.")
130
131
132 def run(server_class=HTTPServer, handler_class=NotifierHandler, port=8662):
133 """Run the webserver application to retrieve alarm notifications."""
134 try:
135 server_address = ('', port)
136 httpd = server_class(server_address, handler_class)
137 print('Starting alarm notifier...')
138 log.info("Starting alarm notifier server on port: %s", port)
139 httpd.serve_forever()
140 except Exception as exc:
141 log.warn("Failed to start webserver, %s", exc)
142
143
144 if __name__ == "__main__":
145 from sys import argv
146
147 # Runs the webserver
148 if len(argv) == 2:
149 run(port=int(argv[1]))
150 else:
151 run()