40e7fe55de062f9bd32f12d0f586779d071e7100
[osm/MON.git] / osm_mon / plugins / CloudWatch / plugin_alarm.py
1 ##
2 # Copyright 2017 xFlow Research Pvt. Ltd
3 # This file is part of MON module
4 # All Rights Reserved.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
16 # under the License.
17 #
18 # For those usages not covered by the Apache License, Version 2.0 please
19 # contact with: wajeeha.hamid@xflowresearch.com
20 ##
21
22 '''
23 AWS-Plugin implements all the methods of MON to interact with AWS using the BOTO client
24 '''
25 from io import open
26 from osm_mon.core.message_bus.producer import KafkaProducer
27 from osm_mon.plugins.CloudWatch.metric_alarms import MetricAlarm
28 from osm_mon.plugins.CloudWatch.metrics import Metrics
29
30 __author__ = "Wajeeha Hamid"
31 __date__ = "18-September-2017"
32
33 import json
34 import logging
35
36 log = logging.getLogger(__name__)
37
38 class plugin_alarms():
39 """Receives Alarm info from MetricAlarm and connects with the consumer/producer"""
40 def __init__ (self):
41 self.metricAlarm = MetricAlarm()
42 self.metric = Metrics()
43 self.producer = KafkaProducer('')
44 #---------------------------------------------------------------------------------------------------------------------------
45 def configure_alarm(self,alarm_info):
46 alarm_id = self.metricAlarm.config_alarm(self.cloudwatch_conn,alarm_info)
47 return alarm_id
48 #---------------------------------------------------------------------------------------------------------------------------
49 def update_alarm_configuration(self,test):
50 alarm_id = self.metricAlarm.update_alarm(self.cloudwatch_conn,test)
51 return alarm_id
52 #---------------------------------------------------------------------------------------------------------------------------
53 def delete_alarm(self,alarm_id):
54 return self.metricAlarm.delete_Alarm(self.cloudwatch_conn,alarm_id)
55 #---------------------------------------------------------------------------------------------------------------------------
56 def get_alarms_list(self,instance_id):
57 return self.metricAlarm.alarms_list(self.cloudwatch_conn,instance_id)
58 #---------------------------------------------------------------------------------------------------------------------------
59 def get_ack_details(self,ack_info):
60 return self.metricAlarm.alarm_details(self.cloudwatch_conn,ack_info)
61 #---------------------------------------------------------------------------------------------------------------------------
62 def get_metrics_data(self,metric_name,period,instance_id):
63 return self.metric.metricsData(self.cloudwatch_conn,metric_name,period,instance_id)
64 #---------------------------------------------------------------------------------------------------------------------------
65
66 def alarm_calls(self,message,aws_conn):
67 """Gets the message from the common consumer"""
68 try:
69 self.cloudwatch_conn = aws_conn['cloudwatch_connection']
70 self.ec2_conn = aws_conn['ec2_connection']
71
72 log.info("Action required against: %s" % (message.topic))
73 alarm_info = json.loads(message.value)
74
75 if message.key == "create_alarm_request":
76 alarm_inner_dict = alarm_info['alarm_create_request']
77 metric_status = self.check_metric(alarm_inner_dict['metric_name'])
78
79 if self.check_resource(alarm_inner_dict['resource_uuid']) == True and metric_status['status'] == True:
80 log.debug ("Resource and Metrics exists")
81
82 alarm_info['alarm_create_request']['metric_name'] = metric_status['metric_name']
83 #Generate a valid response message, send via producer
84 config_resp = self.configure_alarm(alarm_info) #alarm_info = message.value
85
86 if config_resp == None:
87 log.debug("Alarm Already exists")
88 payload = json.dumps(config_resp)
89 file = open('../../core/models/create_alarm_resp.json','wb').write((payload))
90 self.producer.publish_alarm_response(key='create_alarm_response',message=payload)
91
92 else:
93 payload = json.dumps(config_resp)
94 file = open('../../core/models/create_alarm_resp.json','wb').write((payload))
95 self.producer.publish_alarm_response(key='create_alarm_response',message=payload)
96 log.info("New alarm created with alarm info: %s", config_resp)
97
98 else:
99 log.error("Resource ID doesn't exists")
100
101 elif message.key == "acknowledge_alarm":
102 alarm_inner_dict = alarm_info['ack_details']
103
104 if self.check_resource(alarm_inner_dict['resource_uuid']) == True:
105 alarm_info = json.loads(message.value)
106 #Generate a valid response message, send via producer
107 ack_details = self.get_ack_details(alarm_info)
108 payload = json.dumps(ack_details)
109 file = open('../../core/models/notify_alarm.json','wb').write((payload))
110 self.producer.notify_alarm(key='notify_alarm',message=payload)
111 log.info("Acknowledge sent: %s", ack_details)
112
113 else:
114 log.error("Resource ID is Incorrect")
115
116
117 elif message.key == "update_alarm_request":
118 alarm_inner_dict = alarm_info['alarm_update_request']
119 metric_status = self.check_metric(alarm_inner_dict['metric_name'])
120
121 if metric_status['status'] == True:
122 log.debug ("Resource and Metrics exists")
123 alarm_info['alarm_update_request']['metric_name'] = metric_status['metric_name']
124 #Generate a valid response message, send via producer
125 update_resp = self.update_alarm_configuration(alarm_info)
126
127 if update_resp == None:
128 payload = json.dumps(update_resp)
129 file = open('../../core/models/update_alarm_resp.json','wb').write((payload))
130 self.producer.update_alarm_response(key='update_alarm_response',message=payload)
131 log.debug("Alarm Already exists")
132
133 else:
134 payload = json.dumps(update_resp)
135 file = open('../../core/models/update_alarm_resp.json','wb').write((payload))
136 self.producer.update_alarm_response(key='update_alarm_response',message=payload)
137 log.info("Alarm Updated with alarm info: %s", update_resp)
138
139 else:
140 log.info ("Metric Not Supported")
141
142
143 elif message.key == "delete_alarm_request":
144 del_info = json.loads(message.value)
145 #Generate a valid response message, send via producer
146 del_resp = self.delete_alarm(del_info)
147 payload = json.dumps(del_resp)
148 file = open('../../core/models/delete_alarm_resp.json','wb').write((payload))
149 self.producer.delete_alarm_response(key='delete_alarm_response',message=payload)
150 log.info("Alarm Deleted with alarm info: %s", del_resp)
151
152
153 elif message.key == "alarm_list_request":
154 alarm_inner_dict = alarm_info['alarm_list_request']
155
156 if self.check_resource(alarm_inner_dict['resource_uuid']) == True or alarm_inner_dict['resource_uuid'] == "":
157 #Generate a valid response message, send via producer
158 list_resp = self.get_alarms_list(alarm_info)#['alarm_names']
159 payload = json.dumps(list_resp)
160 file = open('../../core/models/list_alarm_resp.json','wb').write((payload))
161 self.producer.list_alarm_response(key='list_alarm_response',message=payload)
162
163 else:
164 log.error("Resource ID is Incorrect")
165
166 else:
167 log.debug("Unknown key, no action will be performed")
168
169 except Exception as e:
170 log.error("Message retrieval exception: %s", str(e))
171 #---------------------------------------------------------------------------------------------------------------------------
172 def check_resource(self,resource_uuid):
173 '''Finding Resource with the resource_uuid'''
174 try:
175 check_resp = dict()
176 instances = self.ec2_conn.get_all_instance_status()
177
178 #resource_id
179 for instance_id in instances:
180 instance_id = str(instance_id).split(':')[1]
181
182 if instance_id == resource_uuid:
183 check_resp['resource_uuid'] = resource_uuid
184 return True
185 return False
186
187 except Exception as e:
188 log.error("Error in Plugin Inputs %s",str(e))
189 #---------------------------------------------------------------------------------------------------------------------------
190 def check_metric(self,metric_name):
191 ''' Checking whether the metric is supported by AWS '''
192 try:
193 check_resp = dict()
194
195 #metric_name
196 if metric_name == 'CPU_UTILIZATION':
197 metric_name = 'CPUUtilization'
198 metric_status = True
199
200 elif metric_name == 'DISK_READ_OPS':
201 metric_name = 'DiskReadOps'
202 metric_status = True
203
204 elif metric_name == 'DISK_WRITE_OPS':
205 metric_name = 'DiskWriteOps'
206 metric_status = True
207
208 elif metric_name == 'DISK_READ_BYTES':
209 metric_name = 'DiskReadBytes'
210 metric_status = True
211
212 elif metric_name == 'DISK_WRITE_BYTES':
213 metric_name = 'DiskWriteBytes'
214 metric_status = True
215
216 elif metric_name == 'PACKETS_RECEIVED':
217 metric_name = 'NetworkPacketsIn'
218 metric_status = True
219
220 elif metric_name == 'PACKETS_SENT':
221 metric_name = 'NetworkPacketsOut'
222 metric_status = True
223
224 else:
225 metric_name = None
226 metric_status = False
227 check_resp['metric_name'] = metric_name
228 #status
229
230 if metric_status == True:
231 check_resp['status'] = True
232 return check_resp
233
234 except Exception as e:
235 log.error("Error in Plugin Inputs %s",str(e))
236 #---------------------------------------------------------------------------------------------------------------------------