c125bab36e5a5fc7a7953a003250dce3d0470024
[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 UnsupportedOperation
26
27 from osm_mon.core.settings import Config
28 from osm_mon.plugins.CloudWatch.metric_alarms import MetricAlarm
29 from osm_mon.plugins.CloudWatch.metrics import Metrics
30
31 __author__ = "Wajeeha Hamid"
32 __date__ = "18-September-2017"
33
34 import logging
35
36 log = logging.getLogger(__name__)
37
38
39 class plugin_alarms:
40 """Receives Alarm info from MetricAlarm and connects with the consumer/producer"""
41
42 def __init__(self):
43 self._cfg = Config.instance()
44 self.metricAlarm = MetricAlarm()
45 self.metric = Metrics()
46
47 def configure_alarm(self, alarm_info):
48 alarm_id = self.metricAlarm.config_alarm(self.cloudwatch_conn, alarm_info)
49 return alarm_id
50
51 def update_alarm_configuration(self, test):
52 alarm_id = self.metricAlarm.update_alarm(self.cloudwatch_conn, test)
53 return alarm_id
54
55 def delete_alarm(self, alarm_id):
56 return self.metricAlarm.delete_Alarm(self.cloudwatch_conn, alarm_id)
57
58 def get_alarms_list(self, instance_id):
59 return self.metricAlarm.alarms_list(self.cloudwatch_conn, instance_id)
60
61 def get_ack_details(self, ack_info):
62 return self.metricAlarm.alarm_details(self.cloudwatch_conn, ack_info)
63
64 def get_metrics_data(self, metric_name, period, instance_id):
65 # TODO: Investigate and fix this call
66 return self.metric.metricsData(self.cloudwatch_conn, metric_name, period, instance_id)
67
68 def alarm_calls(self, key: str, alarm_info: dict, aws_conn: dict):
69 """Gets the message from the common consumer"""
70 try:
71 self.cloudwatch_conn = aws_conn['cloudwatch_connection']
72 self.ec2_conn = aws_conn['ec2_connection']
73
74 if key == "create_alarm_request":
75 alarm_inner_dict = alarm_info['alarm_create_request']
76 metric_status = self.check_metric(alarm_inner_dict['metric_name'])
77
78 if self.check_resource(alarm_inner_dict['resource_uuid']) and metric_status['status']:
79 log.debug("Resource and Metrics exists")
80
81 alarm_info['alarm_create_request']['metric_name'] = metric_status['metric_name']
82 # Generate a valid response message, send via producer
83 config_resp = self.configure_alarm(alarm_info) # alarm_info = message.value
84
85 if config_resp is None:
86 log.debug("Alarm Already exists")
87 # TODO: This should return a response with status False
88 return config_resp
89
90 else:
91 log.info("New alarm created with alarm info: %s", config_resp)
92 return config_resp
93
94 else:
95 log.error("Resource ID doesn't exists")
96
97 elif key == "acknowledge_alarm":
98 alarm_inner_dict = alarm_info['ack_details']
99
100 if self.check_resource(alarm_inner_dict['resource_uuid']):
101 ack_details = self.get_ack_details(alarm_info)
102 log.info("Acknowledge sent: %s", ack_details)
103 return ack_details
104
105 else:
106 log.error("Resource ID is Incorrect")
107
108 elif key == "update_alarm_request":
109 alarm_inner_dict = alarm_info['alarm_update_request']
110 metric_status = self.check_metric(alarm_inner_dict['metric_name'])
111
112 if metric_status['status']:
113 log.debug("Resource and Metrics exists")
114 alarm_info['alarm_update_request']['metric_name'] = metric_status['metric_name']
115 # Generate a valid response message, send via producer
116 update_resp = self.update_alarm_configuration(alarm_info)
117
118 if update_resp is None:
119 # TODO: This should return a response with status False
120 log.debug("Alarm Already exists")
121 return update_resp
122
123 else:
124 log.info("Alarm Updated with alarm info: %s", update_resp)
125 return update_resp
126
127 else:
128 log.info("Metric Not Supported")
129
130 elif key == "delete_alarm_request":
131 # Generate a valid response message, send via producer
132 del_resp = self.delete_alarm(alarm_info)
133 log.info("Alarm Deleted with alarm info: %s", del_resp)
134 return del_resp
135
136 elif key == "alarm_list_request":
137 alarm_inner_dict = alarm_info['alarm_list_request']
138
139 if self.check_resource(alarm_inner_dict['resource_uuid']) or alarm_inner_dict['resource_uuid'] == "":
140 # Generate a valid response message, send via producer
141 list_resp = self.get_alarms_list(alarm_info) # ['alarm_names']
142 return list_resp
143 else:
144 log.error("Resource ID is Incorrect")
145
146 else:
147 raise UnsupportedOperation("Unknown key, no action will be performed")
148
149 except Exception as e:
150 log.error("Message retrieval exception: %s", str(e))
151
152 def check_resource(self, resource_uuid):
153 """Finding Resource with the resource_uuid"""
154 try:
155 check_resp = dict()
156 instances = self.ec2_conn.get_all_instance_status()
157
158 # resource_id
159 for instance_id in instances:
160 instance_id = str(instance_id).split(':')[1]
161
162 if instance_id == resource_uuid:
163 check_resp['resource_uuid'] = resource_uuid
164 return True
165 return False
166
167 except Exception as e:
168 log.error("Error in Plugin Inputs %s", str(e))
169
170 def check_metric(self, metric_name):
171 """ Checking whether the metric is supported by AWS """
172 try:
173 check_resp = dict()
174
175 # metric_name
176 if metric_name == 'CPU_UTILIZATION':
177 metric_name = 'CPUUtilization'
178 metric_status = True
179
180 elif metric_name == 'DISK_READ_OPS':
181 metric_name = 'DiskReadOps'
182 metric_status = True
183
184 elif metric_name == 'DISK_WRITE_OPS':
185 metric_name = 'DiskWriteOps'
186 metric_status = True
187
188 elif metric_name == 'DISK_READ_BYTES':
189 metric_name = 'DiskReadBytes'
190 metric_status = True
191
192 elif metric_name == 'DISK_WRITE_BYTES':
193 metric_name = 'DiskWriteBytes'
194 metric_status = True
195
196 elif metric_name == 'PACKETS_RECEIVED':
197 metric_name = 'NetworkPacketsIn'
198 metric_status = True
199
200 elif metric_name == 'PACKETS_SENT':
201 metric_name = 'NetworkPacketsOut'
202 metric_status = True
203
204 else:
205 metric_name = None
206 metric_status = False
207 check_resp['metric_name'] = metric_name
208 # status
209
210 if metric_status:
211 check_resp['status'] = True
212 return check_resp
213
214 except Exception as e:
215 log.error("Error in Plugin Inputs %s", str(e))