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 gethostname
37 from datetime
import datetime
38 from xml
.etree
import ElementTree
as ET
44 from core
.message_bus
.producer
import KafkaProducer
47 from cheroot
.wsgi
import Server
as WSGIServer
48 from cheroot
.ssl
.pyopenssl
import pyOpenSSLAdapter
50 from cherrypy
.wsgiserver
import CherryPyWSGIServer
as WSGIServer
51 from cherrypy
.wsgiserver
.ssl_pyopenssl
import pyOpenSSLAdapter
54 BASE_DIR
= os
.path
.dirname(os
.path
.dirname(__file__
))
55 CERT_DIR
= os
.path
.join(BASE_DIR
, "SSL_certificate")
56 CERTIFICATE
= os
.path
.join(CERT_DIR
, "www.vrops_webservice.com.cert")
57 KEY
= os
.path
.join(CERT_DIR
, "www.vrops_webservice.com.key")
58 CONFIG_FILE
= os
.path
.join(BASE_DIR
, '../vrops_config.xml')
59 #Severity Mapping from vROPs to OSM
60 VROPS_SEVERITY_TO_OSM_MAPPING
= {
61 "ALERT_CRITICALITY_LEVEL_CRITICAL":"CRITICAL",
62 "ALERT_CRITICALITY_LEVEL_WARNING":"WARNING",
63 "ALERT_CRITICALITY_LEVEL_IMMEDIATE":"MAJOR",
64 "ALERT_CRITICALITY_LEVEL_INFO":"INDETERMINATE",
65 "ALERT_CRITICALITY_LEVEL_AUTO":"INDETERMINATE",
66 "ALERT_CRITICALITY_LEVEL_UNKNOWN":"INDETERMINATE",
67 "ALERT_CRITICALITY_LEVEL_NONE":"INDETERMINATE"
71 logger
= logging
.getLogger('vROPs_Webservice')
72 formatter
= logging
.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
73 hdlr
= logging
.FileHandler(os
.path
.join(BASE_DIR
,"vrops_webservice.log"))
74 hdlr
.setFormatter(formatter
)
75 logger
.addHandler(hdlr
)
76 logger
.setLevel(logging
.DEBUG
)
79 def format_datetime(str_date
):
81 Method to format datetime
83 str_date - datetime string
87 date_fromat
= "%Y-%m-%dT%H:%M:%S"
88 formated_datetime
= None
90 datetime_obj
= datetime
.fromtimestamp(float(str_date
)/1000.)
91 formated_datetime
= datetime_obj
.strftime(date_fromat
)
92 except Exception as exp
:
93 logger
.error('Exception: {} occured while converting date {} into format {}'.format(
94 exp
,str_date
, date_fromat
))
96 return formated_datetime
98 def get_alarm_config():
100 Method to get configuration parameters
104 dictionary of config parameters
108 xml_content
= ET
.parse(CONFIG_FILE
)
109 alarms
= xml_content
.getroot()
111 if alarm
.tag
== 'Access_Config':
113 alarm_config
[param
.tag
] = param
.text
114 except Exception as exp
:
115 logger
.error('Exception: {} occured while parsing config file.'.format(exp
))
119 def get_alarm_definationID(alarm_uuid
):
121 Method to get alarm/alert defination ID
123 alarm_uuid : UUID of alarm
127 alarm_definationID
= None
130 access_config
= get_alarm_config()
131 headers
= {'Accept': 'application/json'}
132 api_url
= '{}/suite-api/api/alerts/{}'.format(access_config
.get('vrops_site'), alarm_uuid
)
133 api_response
= requests
.get(
135 auth
=(access_config
.get('vrops_user'), access_config
.get('vrops_password')),
136 verify
= False, headers
= headers
139 if api_response
.status_code
== 200:
140 data
= api_response
.json()
141 if data
.get("alertDefinitionId") is not None:
142 alarm_definationID
= '-'.join(data
.get("alertDefinitionId").split('-')[1:])
144 logger
.error("Failed to get alert definition ID for alarm {}".format(alarm_uuid
))
145 except Exception as exp
:
146 logger
.error( "Exception occured while getting alert definition ID for alarm : {}".format(exp
, alarm_uuid
))
148 return alarm_definationID
151 @route('/notify/<alarmID>', method
='POST')
152 def notify_alarm(alarmID
):
154 Method notify alarm details by publishing message at Kafka message bus
156 alarmID - Name of alarm
160 logger
.info("Request:{} from:{} {} {} ".format(request
, request
.remote_addr
, request
.method
, request
.url
))
161 response
.headers
['Content-Type'] = 'application/json'
163 postdata
= json
.loads(request
.body
.read())
165 alaram_config
= get_alarm_config()
167 notify_details
['alarm_uuid'] = get_alarm_definationID(postdata
.get('alertId'))
168 notify_details
['description'] = postdata
.get('info')
169 notify_details
['alarm_instance_uuid'] = alarmID
170 notify_details
['resource_uuid'] = '-'.join(postdata
.get('alertName').split('-')[1:])
171 notify_details
['tenant_uuid'] = alaram_config
.get('tenant_id')
172 notify_details
['vim_type'] = "VMware"
173 notify_details
['severity'] = VROPS_SEVERITY_TO_OSM_MAPPING
.get(postdata
.get('criticality'), 'INDETERMINATE')
174 notify_details
['status'] = postdata
.get('status')
175 if postdata
.get('startDate'):
176 notify_details
['start_date_time'] = format_datetime(postdata
.get('startDate'))
177 if postdata
.get('updateDate'):
178 notify_details
['update_date_time'] = format_datetime(postdata
.get('updateDate'))
179 if postdata
.get('cancelDate'):
180 notify_details
['cancel_date_time'] = format_datetime(postdata
.get('cancelDate'))
182 alarm_details
= {'schema_version': 1.0,
183 'schema_type': "notify_alarm",
184 'notify_details': notify_details
186 alarm_data
= json
.dumps(alarm_details
)
187 logger
.info("Alarm details: {}".format(alarm_data
))
189 #Publish Alarm details
190 kafkaMsgProducer
= KafkaProducer()
191 kafkaMsgProducer
.publish(topic
='alarm_response', key
='notify_alarm', value
=alarm_data
)
193 #return 201 on Success
194 response
.status
= 201
196 except Exception as exp
:
197 logger
.error('Exception: {} occured while notifying alarm {}.'.format(exp
, alarmID
))
199 response
.status
= 500
204 class SSLWebServer(ServerAdapter
):
206 CherryPy web server with SSL support.
209 def run(self
, handler
):
211 Runs a CherryPy Server using the SSL certificate.
213 server
= WSGIServer((self
.host
, self
.port
), handler
)
214 server
.ssl_adapter
= pyOpenSSLAdapter(
215 certificate
=CERTIFICATE
,
217 # certificate_chain="intermediate_cert.crt"
222 logger
.info("Started vROPs Web Serverice")
223 except Exception as exp
:
225 logger
.error("Exception: {} Stopped vROPs Web Serverice".format(exp
))
228 if __name__
== "__main__":
229 #Start SSL Web Service
230 logger
.info("Start vROPs Web Serverice")
232 server_names
['sslwebserver'] = SSLWebServer
233 run(app
=app
,host
=gethostname(), port
=8080, server
='sslwebserver')