Merge "Changes in vROPs Plugin. 1.Added specifications for Create, Update, Delete...
[osm/MON.git] / plugins / CloudWatch / metric_alarms.py
index c58987d..bd76c81 100644 (file)
@@ -1,13 +1,41 @@
+##
+# Copyright 2017 xFlow Research Pvt. Ltd
+# This file is part of MON module
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: wajeeha.hamid@xflowresearch.com
+##
+
+''' Handling of alarms requests via BOTO 2.48 '''
+
+__author__ = "Wajeeha Hamid"
+__date__   = "18-September-2017"
+
 import sys
 import os
 import re
 import datetime
 import random
 import sys
 import os
 import re
 import datetime
 import random
+import json
 import logging as log
 from random import randint
 from operator import itemgetter
 from connection import Connection
 
 import logging as log
 from random import randint
 from operator import itemgetter
 from connection import Connection
 
+
 try:
     import boto
     import boto.ec2
 try:
     import boto
     import boto.ec2
@@ -19,31 +47,35 @@ except:
 
 
 class MetricAlarm():
 
 
 class MetricAlarm():
-    """Alarms Functionality Handler -- Cloudwatch """
-    def config_alarm(self,cloudwatch_conn,alarm_info):
-       """Configure or Create a new alarm"""
+    """Alarms Functionality Handler -- Carries out alarming requests and responses via BOTO.Cloudwatch """
+    def __init__(self):
+        self.alarm_resp = dict()
+        self.del_resp = dict()
 
 
+    def config_alarm(self,cloudwatch_conn,create_info):
+       """Configure or Create a new alarm"""
+        inner_dict = dict()
         """ Alarm Name to ID Mapping """
         """ Alarm Name to ID Mapping """
-        alarm_id = alarm_info['alarm_name'] + "_" + alarm_info['resource_id']
-        if self.is_present(cloudwatch_conn,alarm_id) == True: 
+        alarm_info = create_info['alarm_create_request']
+        alarm_id = alarm_info['alarm_name'] + "_" + alarm_info['resource_uuid']
+        if self.is_present(cloudwatch_conn,alarm_id)['status'] == True: 
             alarm_id = None
             log.debug ("Alarm already exists, Try updating the alarm using 'update_alarm_configuration()'")   
         else:              
             try:
                 alarm = boto.ec2.cloudwatch.alarm.MetricAlarm(
                     connection = cloudwatch_conn,
             alarm_id = None
             log.debug ("Alarm already exists, Try updating the alarm using 'update_alarm_configuration()'")   
         else:              
             try:
                 alarm = boto.ec2.cloudwatch.alarm.MetricAlarm(
                     connection = cloudwatch_conn,
-                    name = alarm_info['alarm_name'] + "_" + alarm_info['resource_id'],
-                    metric = alarm_info['alarm_metric'],
-                    namespace = alarm_info['instance_type'],
-                    statistic = alarm_info['alarm_statistics'],
-                    comparison = alarm_info['alarm_comparison'],
-                    threshold = alarm_info['alarm_threshold'],
-                    period = alarm_info['alarm_period'],
-                    evaluation_periods = alarm_info['alarm_evaluation_period'],
-                    unit=alarm_info['alarm_unit'],
-                    description = alarm_info['alarm_severity'] + ";" + alarm_info['alarm_description'],
-                    dimensions = {'InstanceId':alarm_info['resource_id']},
+                    name = alarm_info['alarm_name'] + "_" + alarm_info['resource_uuid'],
+                    metric = alarm_info['metric_name'],
+                    namespace = "AWS/EC2",
+                    statistic = alarm_info['statistic'],
+                    comparison = alarm_info['operation'],
+                    threshold = alarm_info['threshold_value'],
+                    period = 60,
+                    evaluation_periods = 1,
+                    unit=alarm_info['unit'],
+                    description = alarm_info['severity'] + ";" + alarm_id + ";" + alarm_info['description'],
+                    dimensions = {'InstanceId':alarm_info['resource_uuid']},
                     alarm_actions = None,
                     ok_actions = None,
                     insufficient_data_actions = None)
                     alarm_actions = None,
                     ok_actions = None,
                     insufficient_data_actions = None)
@@ -51,126 +83,181 @@ class MetricAlarm():
                 """Setting Alarm Actions : 
                 alarm_actions = ['arn:aws:swf:us-west-2:465479087178:action/actions/AWS_EC2.InstanceId.Stop/1.0']"""
 
                 """Setting Alarm Actions : 
                 alarm_actions = ['arn:aws:swf:us-west-2:465479087178:action/actions/AWS_EC2.InstanceId.Stop/1.0']"""
 
-                cloudwatch_conn.put_metric_alarm(alarm)
+                status=cloudwatch_conn.put_metric_alarm(alarm)
+
                 log.debug ("Alarm Configured Succesfully")
                 log.debug ("Alarm Configured Succesfully")
-                print "created"
-                print "\n"    
+                self.alarm_resp['schema_version'] = str(create_info['schema_version'])
+                self.alarm_resp['schema_type'] = 'create_alarm_response'
+
+                inner_dict['correlation_id'] = str(alarm_info['correlation_id'])
+                inner_dict['alarm_uuid'] = str(alarm_id) 
+                inner_dict['status'] = status
+
+                self.alarm_resp['alarm_create_response'] = inner_dict
+                if status == True:
+                       return self.alarm_resp
+                else:
+                       return None     
+
             except Exception as e:
                 log.error("Alarm Configuration Failed: " + str(e))
             except Exception as e:
                 log.error("Alarm Configuration Failed: " + str(e))
-        return alarm_id    
+            
 #-----------------------------------------------------------------------------------------------------------------------------
 #-----------------------------------------------------------------------------------------------------------------------------
-    def update_alarm(self,cloudwatch_conn,alarm_info):
+    def update_alarm(self,cloudwatch_conn,update_info):
 
        """Update or reconfigure an alarm"""
 
        """Update or reconfigure an alarm"""
-        
+        inner_dict = dict()
+        alarm_info = update_info['alarm_update_request']
+
         """Alarm Name to ID Mapping"""
         """Alarm Name to ID Mapping"""
-        alarm_id = alarm_info['alarm_name'] + "_" + alarm_info['resource_id']
+        alarm_id = alarm_info['alarm_uuid']
+        status = self.is_present(cloudwatch_conn,alarm_id)
 
         """Verifying : Alarm exists already"""
 
         """Verifying : Alarm exists already"""
-        if self.is_present(cloudwatch_conn,alarm_id) == False: 
+        if status['status'] == False: 
             alarm_id = None
             alarm_id = None
-            log.debug("Alarm not found, Try creating the alarm using 'configure_alarm()'")   
+            log.debug("Alarm not found, Try creating the alarm using 'configure_alarm()'")
+            return alarm_id   
         else:            
             try:
                 alarm = boto.ec2.cloudwatch.alarm.MetricAlarm(
         else:            
             try:
                 alarm = boto.ec2.cloudwatch.alarm.MetricAlarm(
-                        connection = cloudwatch_conn,
-                        name = alarm_info['alarm_name'] + "_" + alarm_info['resource_id'],
-                        metric = alarm_info['alarm_metric'],
-                        namespace = alarm_info['instance_type'],
-                        statistic = alarm_info['alarm_statistics'],
-                        comparison = alarm_info['alarm_comparison'],
-                        threshold = alarm_info['alarm_threshold'],
-                        period = alarm_info['alarm_period'],
-                        evaluation_periods = alarm_info['alarm_evaluation_period'],
-                        unit=alarm_info['alarm_unit'],
-                        description = alarm_info['alarm_severity'] + ";" + alarm_info['alarm_description'],
-                        dimensions = {'InstanceId':alarm_info['resource_id']},
-                        alarm_actions = None,
-                        ok_actions = None,
-                        insufficient_data_actions = None)
-                cloudwatch_conn.put_metric_alarm(alarm)
+                    connection = cloudwatch_conn,
+                    name = status['info'].name ,
+                    metric = alarm_info['metric_name'],
+                    namespace = "AWS/EC2",
+                    statistic = alarm_info['statistic'],
+                    comparison = alarm_info['operation'],
+                    threshold = alarm_info['threshold_value'],
+                    period = 60,
+                    evaluation_periods = 1,
+                    unit=alarm_info['unit'],
+                    description = alarm_info['severity'] + ";" + alarm_id + ";" + alarm_info['description'],
+                    dimensions = {'InstanceId':str(status['info'].dimensions['InstanceId']).split("'")[1]},
+                    alarm_actions = None,
+                    ok_actions = None,
+                    insufficient_data_actions = None)
+
+                """Setting Alarm Actions : 
+                alarm_actions = ['arn:aws:swf:us-west-2:465479087178:action/actions/AWS_EC2.InstanceId.Stop/1.0']"""
+
+                status=cloudwatch_conn.put_metric_alarm(alarm)
                 log.debug("Alarm %s Updated ",alarm.name)
                 log.debug("Alarm %s Updated ",alarm.name)
-                print "updated"
+                self.alarm_resp['schema_version'] = str(update_info['schema_version'])
+                self.alarm_resp['schema_type'] = 'update_alarm_response'
+
+                inner_dict['correlation_id'] = str(alarm_info['correlation_id'])
+                inner_dict['alarm_uuid'] = str(alarm_id) 
+                inner_dict['status'] = status
+
+                self.alarm_resp['alarm_update_response'] = inner_dict
+                return self.alarm_resp
             except Exception as e:
                 log.error ("Error in Updating Alarm " + str(e))
             except Exception as e:
                 log.error ("Error in Updating Alarm " + str(e))
-        return alarm_id
+        
 #-----------------------------------------------------------------------------------------------------------------------------
 #-----------------------------------------------------------------------------------------------------------------------------
-    def delete_Alarm(self,cloudwatch_conn,alarm_id):
+    def delete_Alarm(self,cloudwatch_conn,del_info_all):
+
        """Deletes an Alarm with specified alarm_id"""
        """Deletes an Alarm with specified alarm_id"""
+        inner_dict = dict()
+        del_info = del_info_all['alarm_delete_request']
+        status = self.is_present(cloudwatch_conn,del_info['alarm_uuid'])
         try:
         try:
-            if self.is_present(cloudwatch_conn,alarm_id) == True:
-                deleted_alarm=cloudwatch_conn.delete_alarms(alarm_id)
-                return alarm_id
+            if status['status'] == True:                
+                del_status=cloudwatch_conn.delete_alarms(status['info'].name)
+                self.del_resp['schema_version'] = str(del_info_all['schema_version'])
+                self.del_resp['schema_type'] = 'delete_alarm_response'
+                inner_dict['correlation_id'] = str(del_info['correlation_id'])
+                inner_dict['alarm_id'] = str(del_info['alarm_uuid'])
+                inner_dict['status'] = del_status
+                self.del_resp['alarm_deletion_response'] = inner_dict
+                return self.del_resp
             return None 
         except Exception as e:
                 log.error("Alarm Not Deleted: " + str(e))      
 #-----------------------------------------------------------------------------------------------------------------------------
             return None 
         except Exception as e:
                 log.error("Alarm Not Deleted: " + str(e))      
 #-----------------------------------------------------------------------------------------------------------------------------
-    def alarms_list(self,cloudwatch_conn,instance_id):
+    def alarms_list(self,cloudwatch_conn,list_info):
 
 
-       """Get a list of alarms that are present on a particular VM instance"""
-        try:
-            log.debug("Getting Alarm list for %s",instance_id)
-            alarm_dict = dict()
-            alarm_list = []
+        """Get a list of alarms that are present on a particular VIM type"""
+        alarm_list = []
+        alarm_info = dict()
+        try: #id vim 
             alarms = cloudwatch_conn.describe_alarms()
             itr = 0
             for alarm in alarms:
             alarms = cloudwatch_conn.describe_alarms()
             itr = 0
             for alarm in alarms:
-                if str(alarm.dimensions['InstanceId']).split("'")[1] == instance_id:
-                    alarm_list.insert(itr,str(alarm.name))
-                    itr += 1
-            alarm_dict['alarm_names'] = alarm_list
-            alarm_dict['resource_id'] = instance_id   
-            return alarm_dict
+                list_info['alarm_list_request']['alarm_uuid'] = str(alarm.description).split(';')[1]
+                alarm_list.insert(itr,self.alarm_details(cloudwatch_conn,list_info))
+                itr += 1
+            
+            alarm_info['schema_version'] = str(list_info['schema_version'])
+            alarm_info['schema_type'] = 'list_alarm_response'    
+            alarm_info['list_alarm_resp'] = json.dumps(alarm_list)
+
+            return alarm_info                  
         except Exception as e:
                 log.error("Error in Getting List : %s",str(e))    
 #-----------------------------------------------------------------------------------------------------------------------------
         except Exception as e:
                 log.error("Error in Getting List : %s",str(e))    
 #-----------------------------------------------------------------------------------------------------------------------------
-    def alarm_details(self,cloudwatch_conn,alarm_name):
+    def alarm_details(self,cloudwatch_conn,ack_info):
 
        """Get an individual alarm details specified by alarm_name"""
         try:
 
        """Get an individual alarm details specified by alarm_name"""
         try:
-            alarms_details=cloudwatch_conn.describe_alarm_history()       
+            alarms_details=cloudwatch_conn.describe_alarm_history()  
+            alarm_details_all = dict()     
             alarm_details_dict = dict()
             alarm_details_dict = dict()
+            ack_info_all = ack_info
+
+
+            if 'ack_details' in ack_info:
+                ack_info = ack_info['ack_details']
+            elif 'alarm_list_request' in ack_info:
+                ack_info = ack_info['alarm_list_request']    
             
             
+            is_present = self.is_present(cloudwatch_conn,ack_info['alarm_uuid'])
+
             for itr in range (len(alarms_details)):
             for itr in range (len(alarms_details)):
-                if alarms_details[itr].name == alarm_name and 'created' in alarms_details[itr].summary :#name, timestamp, summary
-                    status = alarms_details[itr].summary.split()                   
+                if alarms_details[itr].name == is_present['info'].name :#name, timestamp, summary
+                    if 'created' in alarms_details[itr].summary:
+                        alarm_details_dict['status'] = "New"
+                    elif 'updated' in alarms_details[itr].summary:
+                        alarm_details_dict['status'] = "Update"
+                    elif 'deleted' in alarms_details[itr].summary:   
+                        alarm_details_dict['status'] = "Canceled"
+
+                    status = alarms_details[itr].summary.split()                  
                     alarms = cloudwatch_conn.describe_alarms()
                     for alarm in alarms:
                     alarms = cloudwatch_conn.describe_alarms()
                     for alarm in alarms:
-                        if alarm.name == alarm_name:
-                            alarm_details_dict['alarm_id'] = alarm_name
-                            alarm_details_dict['resource_id'] = str(alarm.dimensions['InstanceId']).split("'")[1]
-                            alarm_details_dict['severity'] = str(alarm.description)
-                            alarm_details_dict['start_date_time'] = str(alarms_details[x].timestamp) 
+                        if str(alarm.description).split(';')[1] == ack_info['alarm_uuid']:
+                            alarm_details_dict['alarm_uuid'] = str(ack_info['alarm_uuid'])
+                            alarm_details_dict['resource_uuid'] = str(alarm.dimensions['InstanceId']).split("'")[1]
+                            alarm_details_dict['description'] = str(alarm.description).split(';')[1]
+                            alarm_details_dict['severity'] = str(alarm.description).split(';')[0]
+                            alarm_details_dict['start_date_time'] = str(alarms_details[itr].timestamp) 
+                            alarm_details_dict['vim_type'] = str(ack_info_all['vim_type'])
+                            #TODO : tenant id
+                            if 'ack_details' in ack_info_all:
+                                alarm_details_all['schema_version'] = str(ack_info_all['schema_version'])
+                                alarm_details_all['schema_type'] = 'notify_alarm'
+                                alarm_details_all['notify_details'] = alarm_details_dict
+                                return alarm_details_all
 
 
-                            return alarm_details_dict             
+                            elif 'alarm_list_request' in ack_info_all:
+                                return alarm_details_dict                     
                   
         except Exception as e:
                log.error("Error getting alarm details: %s",str(e))           
 #-----------------------------------------------------------------------------------------------------------------------------
                   
         except Exception as e:
                log.error("Error getting alarm details: %s",str(e))           
 #-----------------------------------------------------------------------------------------------------------------------------
-    def metrics_data(self,cloudwatch_conn,metric_name,instance_id,period,metric_unit):
-
-       """Getting Metrics Stats for an Hour. Time interval can be modified using Timedelta value"""
-        metric_data= dict()
-        metric_stats=cloudwatch_conn.get_metric_statistics(period, datetime.datetime.utcnow() - datetime.timedelta(seconds=3600),
-                            datetime.datetime.utcnow(),metric_name,'AWS/EC2', 'Maximum',
-                            dimensions={'InstanceId':instance_id}, unit=metric_unit)
-
-        for itr in range (len(metric_stats)):
-            metric_data['metric_name'] = metric_name
-            metric_data['Resource_id'] = instance_id
-            metric_data['Unit']                   = metric_stats[itr]['Unit']
-            metric_data['Timestamp']   = metric_stats[itr]['Timestamp']  
-        return metric_data
-
-#-----------------------------------------------------------------------------------------------------------------------------
-    def is_present(self,cloudwatch_conn,alarm_name):
-       """Finding Alarm exists or not"""
+    def is_present(self,cloudwatch_conn,alarm_id):
+       """Finding alarm from already configured alarms"""
+        alarm_info = dict()
         try:
             alarms = cloudwatch_conn.describe_alarms()
             for alarm in alarms:
         try:
             alarms = cloudwatch_conn.describe_alarms()
             for alarm in alarms:
-                if alarm.name == alarm_name:
-                    return True
-            return False
+                if str(alarm.description).split(';')[1] == alarm_id:
+                    alarm_info['status'] = True
+                    alarm_info['info'] = alarm
+                    return alarm_info
+            alarm_info['status'] = False        
+            return alarm_info
         except Exception as e:
                 log.error("Error Finding Alarm",str(e))             
 #-----------------------------------------------------------------------------------------------------------------------------
         except Exception as e:
                 log.error("Error Finding Alarm",str(e))             
 #-----------------------------------------------------------------------------------------------------------------------------
+    
\ No newline at end of file