2 # -*- coding: utf-8 -*-
5 # Copyright 2016-2017 VMware Inc.
6 # This file is part of ETSI OSM
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact: osslegalrouting@vmware.com
26 Webservice for vRealize Operations (vROPs) to post/notify alarms details.
29 __author__ = "Arpita Kate"
30 __date__ = "$15-Sept-2017 16:09:29$"
34 from bottle import (ServerAdapter, route, run, server_names, redirect, default_app,
35 request, response, template, debug, TEMPLATE_PATH , static_file)
36 from socket import getfqdn
37 from datetime import datetime
38 from xml.etree import ElementTree as ET
44 sys.path.append("../../../core/message_bus")
45 from producer import KafkaProducer
46 #from core.message_bus.producer import KafkaProducer
49 from cheroot.wsgi import Server as WSGIServer
50 from cheroot.ssl.pyopenssl import pyOpenSSLAdapter
52 from cherrypy.wsgiserver import CherryPyWSGIServer as WSGIServer
53 from cherrypy.wsgiserver.ssl_pyopenssl import pyOpenSSLAdapter
56 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
57 CERT_DIR = os.path.join(BASE_DIR, "SSL_certificate")
58 certificate_name = getfqdn() + ".cert"
59 key_name = getfqdn() + ".key"
60 CERTIFICATE = os.path.join(CERT_DIR, certificate_name)
61 KEY = os.path.join(CERT_DIR, key_name)
62 #CERTIFICATE = os.path.join(CERT_DIR, "www.vrops_webservice.com.cert")
63 #KEY = os.path.join(CERT_DIR, "www.vrops_webservice.com.key")
64 CONFIG_FILE = os.path.join(BASE_DIR, '../vrops_config.xml')
65 #Severity Mapping from vROPs to OSM
66 VROPS_SEVERITY_TO_OSM_MAPPING = {
67 "ALERT_CRITICALITY_LEVEL_CRITICAL":"CRITICAL",
68 "ALERT_CRITICALITY_LEVEL_WARNING":"WARNING",
69 "ALERT_CRITICALITY_LEVEL_IMMEDIATE":"MAJOR",
70 "ALERT_CRITICALITY_LEVEL_INFO":"INDETERMINATE",
71 "ALERT_CRITICALITY_LEVEL_AUTO":"INDETERMINATE",
72 "ALERT_CRITICALITY_LEVEL_UNKNOWN":"INDETERMINATE",
73 "ALERT_CRITICALITY_LEVEL_NONE":"INDETERMINATE"
77 logger = logging.getLogger('vROPs_Webservice')
78 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
79 hdlr = logging.FileHandler(os.path.join(BASE_DIR,"vrops_webservice.log"))
80 hdlr.setFormatter(formatter)
81 logger.addHandler(hdlr)
82 logger.setLevel(logging.DEBUG)
85 def format_datetime(str_date):
87 Method to format datetime
89 str_date - datetime string
93 date_fromat = "%Y-%m-%dT%H:%M:%S"
94 formated_datetime = None
96 datetime_obj = datetime.fromtimestamp(float(str_date)/1000.)
97 formated_datetime = datetime_obj.strftime(date_fromat)
98 except Exception as exp:
99 logger.error('Exception: {} occured while converting date {} into format {}'.format(
100 exp,str_date, date_fromat))
102 return formated_datetime
104 def get_alarm_config():
106 Method to get configuration parameters
110 dictionary of config parameters
114 xml_content = ET.parse(CONFIG_FILE)
115 alarms = xml_content.getroot()
117 if alarm.tag == 'Access_Config':
119 alarm_config[param.tag] = param.text
120 except Exception as exp:
121 logger.error('Exception: {} occured while parsing config file.'.format(exp))
125 def get_alarm_definationID(alarm_uuid):
127 Method to get alarm/alert defination ID
129 alarm_uuid : UUID of alarm
133 alarm_definationID = None
136 access_config = get_alarm_config()
137 headers = {'Accept': 'application/json'}
138 api_url = '{}/suite-api/api/alerts/{}'.format(access_config.get('vrops_site'), alarm_uuid)
139 api_response = requests.get(
141 auth=(access_config.get('vrops_user'), access_config.get('vrops_password')),
142 verify = False, headers = headers
145 if api_response.status_code == 200:
146 data = api_response.json()
147 if data.get("alertDefinitionId") is not None:
148 alarm_definationID = '-'.join(data.get("alertDefinitionId").split('-')[1:])
150 logger.error("Failed to get alert definition ID for alarm {}".format(alarm_uuid))
151 except Exception as exp:
152 logger.error( "Exception occured while getting alert definition ID for alarm : {}".format(exp, alarm_uuid))
154 return alarm_definationID
157 @route('/notify/<alarmID>', method='POST')
158 def notify_alarm(alarmID):
160 Method notify alarm details by publishing message at Kafka message bus
162 alarmID - Name of alarm
166 logger.info("Request:{} from:{} {} {} ".format(request, request.remote_addr, request.method, request.url))
167 response.headers['Content-Type'] = 'application/json'
169 postdata = json.loads(request.body.read())
171 alaram_config = get_alarm_config()
173 notify_details['alarm_uuid'] = get_alarm_definationID(postdata.get('alertId'))
174 notify_details['description'] = postdata.get('info')
175 notify_details['alarm_instance_uuid'] = alarmID
176 notify_details['resource_uuid'] = '-'.join(postdata.get('alertName').split('-')[1:])
177 notify_details['tenant_uuid'] = alaram_config.get('tenant_id')
178 notify_details['vim_type'] = "VMware"
179 notify_details['severity'] = VROPS_SEVERITY_TO_OSM_MAPPING.get(postdata.get('criticality'), 'INDETERMINATE')
180 notify_details['status'] = postdata.get('status')
181 if postdata.get('startDate'):
182 notify_details['start_date_time'] = format_datetime(postdata.get('startDate'))
183 if postdata.get('updateDate'):
184 notify_details['update_date_time'] = format_datetime(postdata.get('updateDate'))
185 if postdata.get('cancelDate'):
186 notify_details['cancel_date_time'] = format_datetime(postdata.get('cancelDate'))
188 alarm_details = {'schema_version': 1.0,
189 'schema_type': "notify_alarm",
190 'notify_details': notify_details
192 alarm_data = json.dumps(alarm_details)
193 logger.info("Alarm details: {}".format(alarm_data))
195 #Publish Alarm details
196 kafkaMsgProducer = KafkaProducer("alarm_response")
197 kafkaMsgProducer.publish(topic='alarm_response', key='notify_alarm', value=alarm_data)
199 #return 201 on Success
200 response.status = 201
202 except Exception as exp:
203 logger.error('Exception: {} occured while notifying alarm {}.'.format(exp, alarmID))
205 response.status = 500
210 class SSLWebServer(ServerAdapter):
212 CherryPy web server with SSL support.
215 def run(self, handler):
217 Runs a CherryPy Server using the SSL certificate.
219 server = WSGIServer((self.host, self.port), handler)
220 server.ssl_adapter = pyOpenSSLAdapter(
221 certificate=CERTIFICATE,
223 # certificate_chain="intermediate_cert.crt"
228 logger.info("Started vROPs Web Service")
229 except Exception as exp:
231 logger.error("Exception: {} Stopped vROPs Web Service".format(exp))
234 if __name__ == "__main__":
235 #Start SSL Web Service
236 logger.info("Start vROPs Web Service")
238 server_names['sslwebserver'] = SSLWebServer
239 run(app=app,host=getfqdn(), port=8080, server='sslwebserver')