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)
Exemple #2
0
    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']})
Exemple #3
0
    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)
Exemple #5
0
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}))
Exemple #6
0
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}))