| Benjamin Diaz | 6eda48b | 2018-11-21 10:52:05 -0300 | [diff] [blame^] | 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)) |