class BotoWatchInterface(WatchInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): #boto.set_stream_logger('foo') path='/services/CloudWatch' port=8773 if clc_host[len(clc_host)-13:] == 'amazonaws.com': clc_host = clc_host.replace('ec2', 'monitoring', 1) path = '/' reg = None port=443 reg = RegionInfo(name='eucalyptus', endpoint=clc_host) self.conn = CloudWatchConnection(access_id, secret_key, region=reg, port=port, path=path, is_secure=True, security_token=token, debug=0) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs['timeout'] = 30 def __save_json__(self, obj, name): f = open(name, 'w') json.dump(obj, f, cls=BotoJsonWatchEncoder, indent=2) f.close() def get_metric_statistics(self, period, start_name, end_time, metric_name, namespace, statistics, dimensions, unit): obj = self.conn.get_metric_statistics(period, start_name, end_time, metric_name, namespace, statistics, dimensions, unit) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Statistics.json") return obj def list_metrics(self, next_token=None, dimensions=None, metric_name=None, namespace=None): obj = self.conn.list_metrics(next_token, dimensions, metric_name, namespace) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Metrics.json") return obj def put_metric_data(self, namespace, name, value, timestamp, unit, dimensions, statistics): return self.conn.put_metric_data(namespace, name, value, timestamp, unit, dimensions, statistics) def describe_alarms(self, action_prefix=None, alarm_name_prefix=None, alarm_names=None, max_records=None, state_value=None, next_token=None): obj = self.conn.describe_alarms(action_prefix, alarm_name_prefix, alarm_names, max_records, state_value, next_token) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Alarms.json") return obj def delete_alarms(self, alarm_names): return self.conn.delete_alarms(alarm_names) def enable_alarm_actions(self, alarm_names): return self.conn.enable_alarm_actions(alarm_names) def disable_alarm_actions(self, alarm_names): return self.conn.disable_alarm_actions(alarm_names) def put_metric_alarm(self, alarm): return self.conn.put_metric_alarm(alarm)
def test_describe_alarms(self): c = CloudWatchConnection() def make_request(*args, **kwargs): class Body(object): def __init__(self): self.status = 200 def read(self): return DESCRIBE_ALARMS_BODY return Body() c.make_request = make_request alarms = c.describe_alarms() self.assertEquals(alarms[0].name, 'FancyAlarm') self.assertEquals(alarms[0].comparison, '<') self.assertEquals(alarms[0].dimensions, {u'Job': [u'ANiceCronJob']}) self.assertEquals(alarms[1].name, 'SuperFancyAlarm') self.assertEquals(alarms[1].comparison, '>') self.assertEquals(alarms[1].dimensions, {u'Job': [u'ABadCronJob']})
def test_describe_alarms(self): c = CloudWatchConnection() def make_request(*args, **kwargs): class Body(object): def __init__(self): self.status = 200 def read(self): return DESCRIBE_ALARMS_BODY return Body() c.make_request = make_request alarms = c.describe_alarms() self.assertEquals(alarms.next_token, 'mynexttoken') self.assertEquals(alarms[0].name, 'FancyAlarm') self.assertEquals(alarms[0].comparison, '<') self.assertEquals(alarms[0].dimensions, {u'Job': [u'ANiceCronJob']}) self.assertEquals(alarms[1].name, 'SuperFancyAlarm') self.assertEquals(alarms[1].comparison, '>') self.assertEquals(alarms[1].dimensions, {u'Job': [u'ABadCronJob']})
class BotoWatchInterface(WatchInterface): conn = None saveclcdata = False def __init__(self, clc_host, access_id, secret_key, token): # boto.set_stream_logger('foo') path = "/services/CloudWatch" port = 8773 if clc_host[len(clc_host) - 13 :] == "amazonaws.com": clc_host = clc_host.replace("ec2", "monitoring", 1) path = "/" reg = None port = 443 reg = RegionInfo(name="eucalyptus", endpoint=clc_host) self.conn = CloudWatchConnection( access_id, secret_key, region=reg, port=port, path=path, is_secure=True, security_token=token, debug=0 ) self.conn.https_validate_certificates = False self.conn.http_connection_kwargs["timeout"] = 30 def __save_json__(self, obj, name): f = open(name, "w") json.dump(obj, f, cls=BotoJsonWatchEncoder, indent=2) f.close() def get_metric_statistics(self, period, start_name, end_time, metric_name, namespace, statistics, dimensions, unit): obj = self.conn.get_metric_statistics( period, start_name, end_time, metric_name, namespace, statistics, dimensions, unit ) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Statistics.json") return obj def list_metrics(self, next_token=None, dimensions=None, metric_name=None, namespace=None): obj = self.conn.list_metrics(next_token, dimensions, metric_name, namespace) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Metrics.json") return obj def put_metric_data(self, namespace, name, value, timestamp, unit, dimensions, statistics): return self.conn.put_metric_data(namespace, name, value, timestamp, unit, dimensions, statistics) def describe_alarms( self, action_prefix=None, alarm_name_prefix=None, alarm_names=None, max_records=None, state_value=None, next_token=None, ): obj = self.conn.describe_alarms( action_prefix, alarm_name_prefix, alarm_names, max_records, state_value, next_token ) if self.saveclcdata: self.__save_json__(obj, "mockdata/CW_Alarms.json") return obj def delete_alarms(self, alarm_names): return self.conn.delete_alarms(alarm_names) def enable_alarm_actions(self, alarm_names): return self.conn.enable_alarm_actions(alarm_names) def disable_alarm_actions(self, alarm_names): return self.conn.disable_alarm_actions(alarm_names) def put_metric_alarm(self, alarm): return self.conn.put_metric_alarm(alarm)
class DiscoAlarm(object): """ Class orchestrating CloudWatch alarms """ def __init__(self, disco_sns=None): self.cloudwatch = CloudWatchConnection() self._disco_sns = disco_sns def upsert_alarm(self, alarm): """ Create an alarm, delete and re-create if it already exists """ existing_alarms = self.cloudwatch.describe_alarms( alarm_names=[alarm.name]) for existing_alarm in existing_alarms: throttled_call(existing_alarm.delete) throttled_call(self.cloudwatch.create_alarm, alarm) @property def disco_sns(self): """ Lazy sns connection """ self._disco_sns = self._disco_sns or DiscoSNS() return self._disco_sns def _sns_topic(self, alarm): """ retrieve SNS topic correspoding to the alarm """ return self.disco_sns.topic_arn_from_name(alarm.notification_topic) def create_alarms(self, alarms): """ Create alarms from dict of DiscoAlarmConfig objects. """ for alarm in alarms: self.upsert_alarm(alarm.to_metric_alarm(self._sns_topic(alarm))) def alarms(self): """ Iterate alarms """ next_token = None while True: alarms = throttled_call( self.cloudwatch.describe_alarms, next_token=next_token, ) for alarm in alarms: yield alarm next_token = alarms.next_token if not next_token: break def get_alarms(self, desired=None): """ Get all alarms for an environment filtered on the desired dictionary keys """ desired = desired or {} keys = set(desired.keys()) def _key_filter(dictionary, keys): return { key: value for key, value in dictionary.iteritems() if key in keys } return [ alarm for alarm in self.alarms() if _key_filter(DiscoAlarmConfig.decode_alarm_name(alarm.name), keys) == desired ] def _delete_alarms(self, alarms): alarm_names = [alarm.name for alarm in alarms] alarm_len = len(alarm_names) logging.debug("Deleting %s alarms.", alarm_len) for index in range(0, alarm_len, DELETE_BATCH_SIZE): throttled_call( self.cloudwatch.delete_alarms, alarm_names[index:min(index + DELETE_BATCH_SIZE, alarm_len)]) def delete_hostclass_environment_alarms(self, environment, hostclass): """ Delete alarm in an environment by hostclass name """ self._delete_alarms( self.get_alarms({ "env": environment, "hostclass": hostclass })) def delete_environment_alarms(self, environment): """ Delete all alarms for an environment """ self._delete_alarms(self.get_alarms({"env": environment}))
class DiscoAlarm(object): """ Class orchestrating CloudWatch alarms """ def __init__(self, disco_sns=None): self.cloudwatch = CloudWatchConnection() self._disco_sns = disco_sns def upsert_alarm(self, alarm): """ Create an alarm, delete and re-create if it already exists """ existing_alarms = self.cloudwatch.describe_alarms(alarm_names=[alarm.name]) for existing_alarm in existing_alarms: throttled_call( existing_alarm.delete ) throttled_call( self.cloudwatch.create_alarm, alarm ) @property def disco_sns(self): """ Lazy sns connection """ self._disco_sns = self._disco_sns or DiscoSNS() return self._disco_sns def _sns_topic(self, alarm): """ retrieve SNS topic correspoding to the alarm """ return self.disco_sns.topic_arn_from_name(alarm.notification_topic) def create_alarms(self, alarms): """ Create alarms from dict of DiscoAlarmConfig objects. """ for alarm in alarms: self.upsert_alarm( alarm.to_metric_alarm( self._sns_topic(alarm) ) ) def alarms(self): """ Iterate alarms """ next_token = None while True: alarms = throttled_call( self.cloudwatch.describe_alarms, next_token=next_token, ) for alarm in alarms: yield alarm next_token = alarms.next_token if not next_token: break def get_alarms(self, desired=None): """ Get all alarms for an environment filtered on the desired dictionary keys """ desired = desired or {} keys = set(desired.keys()) def _key_filter(dictionary, keys): return {key: value for key, value in dictionary.iteritems() if key in keys} return [alarm for alarm in self.alarms() if _key_filter(DiscoAlarmConfig.decode_alarm_name(alarm.name), keys) == desired] def _delete_alarms(self, alarms): alarm_names = [alarm.name for alarm in alarms] alarm_len = len(alarm_names) logging.debug("Deleting %s alarms.", alarm_len) for index in range(0, alarm_len, DELETE_BATCH_SIZE): throttled_call( self.cloudwatch.delete_alarms, alarm_names[index:min(index + DELETE_BATCH_SIZE, alarm_len)] ) def delete_hostclass_environment_alarms(self, environment, hostclass): """ Delete alarm in an environment by hostclass name """ self._delete_alarms(self.get_alarms({"env": environment, "hostclass": hostclass})) def delete_environment_alarms(self, environment): """ Delete all alarms for an environment """ self._delete_alarms(self.get_alarms({"env": environment}))