예제 #1
0
class Wrapper(BaseWrapper):
    def __init__(self):
        super(Wrapper, self).__init__()
        self.device = Device(self.token)
        self.service = Service(self.token)
        self.alert = Alert(self.token)

    def results_of(self, command, typeof, name):
        if typeof == 'help' or command == 'help':
            result = self.extra_help(command)
        elif command == 'open alerts':
            result = self.list_alerts(command, typeof, name)
        elif command == 'devices':
            result = self.get_devices(typeof)
        elif command == 'services':
            result = self.get_services(typeof)
        return result

    def get_services(self, number):
        services = self.service.list()
        if number:
            services = services[:int(number)]
        else:
            services = services[:5]

        http = [s for s in services if s['checkType'] == 'http']
        tcp = [s for s in services if s['checkType'] == 'tcp']

        slack_http = [{
            'text': '*Service Name*: {}'.format(service['name']),
            'color': COLOR,
            'mrkdwn_in': ['text'],
            'fields': [{
                    'title': 'Group',
                    'value': service.get('group') if service.get('group') else 'Ungrouped',
                    'short': True
                },
                {
                    'title': 'Type of check',
                    'value': service.get('checkType'),
                    'short': True
                },
                {
                    'title': 'Url',
                    'value': service.get('checkUrl'),
                    'short': True
                },
                {
                    'title': 'Method',
                    'value': service.get('checkMethod'),
                    'short': True
                },
                {
                    'title': 'Slow threshold',
                    'value': str(service.get('slowThreshold')) + 'ms',
                    'short': True
                }
            ]
        } for service in http]

        slack_tcp = [{
            'text': '*Service Name*: {}'.format(service['name']),
            'color': COLOR,
            'mrkdwn_in': ['text'],
            'fields': [{
                    'title': 'Group',
                    'value': service.get('group') if service.get('group') else 'Ungrouped',
                    'short': True
                },
                {
                    'title': 'Type of check',
                    'value': service.get('checkType'),
                    'short': True
                },
                {
                    'title': 'Host',
                    'value': service.get('host'),
                    'short': True
                },
                {
                    'title': 'Port',
                    'value': service.get('port'),
                    'short': True
                }
            ]
        } for service in tcp]
        if not number:
            message = 'Here are 5 services, if you want to see more than that you can, just do `sdbot list services <number>`'
        else:
            message = 'Here are all your {} services'.format(len(slack_tcp + slack_http))
        return slack_tcp + slack_http, message

    def get_devices(self, number):
        devices = self.device.list()
        if number:
            devices = devices[:int(number)]
        else:
            devices = devices[:5]
        # list expression
        slack_formatting = [{
            'text': '*Device Name*: {}'.format(device['name']),
            'color': COLOR,
            'mrkdwn_in': ['text'],
            'fields': [{
                    'title': 'Group',
                    'value': device.get('group') if device.get('group') else 'Ungrouped',
                    'short': True
                },
                {
                    'title': 'Provider',
                    'value': device.get('provider') if device.get('provider') else 'No provider',
                    'short': True
                },
                {
                    'title': 'Id',
                    'value': device.get('_id'),
                    'short': True
                },
                {
                    'title': 'Online Status',
                    'value': self.online_status(device.get('lastPayloadAt', '')),
                    'short': True
                }
            ]
        } for device in devices]
        if not number:
            message = 'Here are 5 devices, if you want to see more than that you can, just do `sdbot list devices <number>`'
        else:
            message = 'Here are your devices'
        return slack_formatting, message

    def extra_help(self, command):
        help_command = {
            'open alerts': {
                'title': 'Open Alerts',
                'mrkdwn_in': ['text'],
                'text': ('The full command for `open alerts` is `open alerts' +
                         ' <type> <name>` where `type` is either a `device`' +
                         ', `service` or a `group`. `name` is the name of that ' +
                         'entity. Both `type` and `name` is optional. If ' +
                         'none is used I will give you 5 alerts by default, ' +
                         'if you want all alerts write `list open alerts all` ' +
                         'instead.'),
                'color': COLOR
            },
            'devices': {
                'title': 'Devices',
                'mrkdwn_in': ['text'],
                'text': ('The full command for `devices` is `devices <number>`' +
                         ', if a number is not specified I will give you 5 ' +
                         'devices by default'),
                'color': COLOR
            },
            'services': {
                'title': 'Services',
                'mrkdwn_in': ['text'],
                'text': ('The full command for listing services is ' +
                         '`sdbot list services <number>`, if a number is not ' +
                         'specified I will give you 5 services by default'),
                'color': COLOR
            }
        }

        if command == 'open alerts':
            helptext = [help_command['open alerts']]
        elif command == 'devices':
            helptext = [help_command['devices']]
        elif command == 'services':
            helptext = [help_command['services']]
        elif command == 'help':
            helptext = [attachment for attachment in help_command.values()]
        return helptext, ''

    def list_alerts(self, command, typeof, name):
        params = {
            'filter': {'fixed': False}
        }
        valid = ['service', 'device']
        if typeof and typeof in valid:
            params['filter']['config.subjectType'] = typeof
        elif typeof == 'group':
            params['filter']['subjectGroup'] = typeof
        else:
            text = 'Instead of `{}` you should have used `group`, `service`, `device` or `all`'.format(typeof), ''
            return text

        services = self.service.list()
        devices = self.device.list()

        if name:
            _id = name if not name else self.find_id(name, services, devices)
            params['filter']['config.subjectId'] = _id

        if typeof == 'group':
            _id = ''

        results = self.alert.triggered(params=params)
        alerts = sorted(results, key=lambda alert: alert['config']['lastTriggeredAt']['sec'], reverse=True)
        if not typeof or name:
            # When making a standard `list open alerts` we want to give a limited amount of alerts.
            stripped_alerts = alerts[:5]
        else:
            # we want to keep the entire list here
            stripped_alerts = alerts
        open_alerts = []
        for alert in stripped_alerts:
            field = alert['config']['fullName'].split(' > ')
            comparison = alert['config'].get('fullComparison') if alert['config'].get('fullComparison') else ''
            value = alert['config'].get('value') if alert['config'].get('value') else ''
            group = alert['config']['group'] if alert['config'].get('group') else 'Ungrouped'
            triggered_time = time.localtime(alert['config']['lastTriggeredAt']['sec'])

            _id = alert['config']['subjectId']
            name = self.find_name(_id, services, devices)
            attachment = {
                'title': '{}'.format(name),
                'text': '{} {} {}'.format(
                    field[1],
                    comparison,
                    value
                ),
                'color': COLOR,
                'fields': [
                    {
                        'title': 'Last triggered',
                        'value': time.strftime('%Y-%m-%d, %H:%M:%S', triggered_time)
                    },
                    {
                        'title': 'Group',
                        'value': group,
                        'short': True
                    }
                ]
            }
            open_alerts.append(attachment)
        if open_alerts:
            if len(alerts) > len(stripped_alerts):
                message = ('You have {} open alerts but I\'m only showing the last {},'.format(len(alerts), len(stripped_alerts)) +
                           ' do `list open alerts all` to see all of them')
            else:
                message = 'Chop chop, you\'d better sort out these open alerts soon'
            return open_alerts, message
        else:
            return 'I could not find any open alerts for you.', ''
예제 #2
0
class AlertTest(BaseTest):
    @patch.object(ApiClient, '_make_request')
    def setUp(self, mock_make_request):
        self.alertobj = self.get_json('/json/alert.json')

        self.client = ApiClient('aeou')
        self.client._make_request = mock_make_request
        self.client._make_request.return_value = self.alertobj
        self.alert = Alert(api=self.client)

    def test_alert_create(self):
        data = {'data': 'alert'}
        self.alert.create(data)
        self.client._make_request.assert_called_with(data=data,
                                                     method='POST',
                                                     url=Alert.PATHS['create'],
                                                     params=None)

    def test_alert_delete(self):
        self.alert.delete(1)
        self.client._make_request.assert_called_with(
            data=None,
            method='DELETE',
            url=Alert.PATHS['delete'].format(1),
            params=None)

    def test_alert_list(self):
        self.client._make_request.return_value = [self.alertobj]
        self.alert.list()
        self.client._make_request.assert_called_with(data=None,
                                                     method='GET',
                                                     url=Alert.PATHS['list'],
                                                     params=None)

    def test_alert_update(self):
        data = {'name': 'test', 'type': 'alert'}
        self.alert.update(_id=1, data=data)
        self.client._make_request.assert_called_with(
            data=data,
            method='PUT',
            url=Alert.PATHS['update'].format(1),
            params=None)

    def test_alert_view(self):
        self.alert.view(1)
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['view'].format(1),
            params=None)

    def test_alert_triggered(self):
        self.client._make_request.return_value = [self.alertobj]
        self.alert.triggered(1, 'device', True)
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['triggered'],
            params={
                'filter':
                '{"config.subjectId": 1, "config.subjectType": "device", "fixed": true}'
            })

    def test_alert_device_metrics(self):
        self.alert.device_metrics()
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['device_metrics'],
            params=None)

    def test_alert_service_metrics(self):
        self.alert.service_metrics()
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['service_metrics'],
            params=None)
예제 #3
0
class Wrapper(BaseWrapper):
    def __init__(self, msg, server):
        super(Wrapper, self).__init__(msg, server)
        self.alert = Alert(self.token)
        self.device = Device(self.token)
        self.service = Service(self.token)

    def results_of(self, command, typeof, name):
        if typeof == 'help' or command == 'help':
            result = self.extra_help(command)
        elif command == 'list':
            result = self.list_alerts(command, typeof, name)
        return result

    def extra_help(self, command):
        help_command = {
            'list': {
                'title': 'List Open Alerts',
                'mrkdwn_in': ['text'],
                'text': ('The full command for alerts is `sdbot alerts list' +
                         ' <type> <name>`, where `type` is either the word `device`' +
                         ', `service` or `group`. The argument `name` corresponds to the ' +
                         'name of that entity. Both `type` and `name` are optional. If ' +
                         'none is used I will give you 5 alerts by default. ' +
                         'If you want all alerts write, type `sdbot alerts list all`.'),
                'color': COLOR
            }
        }

        if command == 'list':
            helptext = [help_command['list']]
        elif command == 'help':
            helptext = [attachment for attachment in help_command.values()]
        return helptext, ''

    def _is_mongoId(self, _id):
        if len(_id) == 24:
            return True
        return False

    def list_alerts(self, command, typeof, name):
        params = {
            'filter': {'fixed': False}
        }
        valid = ['service', 'device']
        if typeof and typeof in valid:
            params['filter']['config.subjectType'] = typeof
        elif typeof == 'group':
            params['filter']['subjectGroup'] = name
        elif typeof in ['all', '']:
            pass  # don't need to do anything
        else:
            text = 'Instead of `{}` you should have used `group`, `service`, `device` or `all`'.format(typeof), ''
            return text

        services = self.service.list()
        devices = self.device.list()

        if name and typeof != 'group':
            _id = name if not name else self.find_id(name, services, devices)
            params['filter']['config.subjectId'] = _id

        results = self.alert.triggered(params=params)
        alerts = sorted(results, key=lambda alert: alert['config']['lastTriggeredAt']['sec'], reverse=True)
        if not (typeof or name):
            # When making a standard `alerts list` we want to give a limited amount of alerts.
            stripped_alerts = alerts[:5]
        else:
            # we want to keep the entire list here
            stripped_alerts = alerts
        open_alerts = []

        for alert in stripped_alerts:
            field = alert['config']['fullName'].split(' > ')
            comparison = alert['config'].get('fullComparison', '')
            value = '{}{}'.format(alert['config'].get('value', ''), alert['config'].get('units', ''))
            group = alert['config'].get('group', 'Ungrouped')
            triggered_time = time.localtime(alert['config']['lastTriggeredAt']['sec'])

            _id = alert['config']['subjectId']
            if self._is_mongoId(_id):
                name = self.find_name(_id, services, devices)
                name = '{}: {}'.format(alert['config']['subjectType'].title(), name)
            else:
                name = 'Group: {}'.format(_id)

            attachment = {
                'title': '{}'.format(name),
                'text': '{} {} {}'.format(
                    field[1],
                    comparison,
                    value
                ),
                'color': COLOR,
                'fields': [
                    {
                        'title': 'Last triggered',
                        'value': time.strftime('%Y-%m-%d, %H:%M:%S', triggered_time)
                    },
                    # waiting on backend bugfix sd-2190
                    # {
                    #     'title': 'Group',
                    #     'value': group,
                    #     'short': True
                    # }
                ]
            }
            open_alerts.append(attachment)
        if open_alerts:
            if len(alerts) > len(stripped_alerts):
                message = ('You have {} open alerts but I\'m only showing the last {},'.format(len(alerts), len(stripped_alerts)) +
                           ' do `list open alerts all` to see all of them')
            else:
                message = 'Chop chop, you\'d better sort out these open alerts soon'
            return open_alerts, message
        else:
            return 'I could not find any open alerts for you.', ''
예제 #4
0
class Wrapper(BaseWrapper):
    def __init__(self, msg, server):
        super(Wrapper, self).__init__(msg, server)
        self.alert = Alert(self.token)
        self.device = Device(self.token)
        self.service = Service(self.token)

    def results_of(self, command, typeof, name):
        if typeof == 'help' or command == 'help':
            result = self.extra_help(command)
        elif command == 'list':
            result = self.list_alerts(command, typeof, name)
        return result

    def extra_help(self, command):
        help_command = {
            'list': {
                'title':
                'List Open Alerts',
                'mrkdwn_in': ['text'],
                'text':
                ('The full command for alerts is `sdbot alerts list' +
                 ' <type> <name>`, where `type` is either the word `device`' +
                 ', `service` or `group`. The argument `name` corresponds to the '
                 +
                 'name of that entity. Both `type` and `name` are optional. If '
                 + 'none is used I will give you 5 alerts by default. ' +
                 'If you want all alerts write, type `sdbot alerts list all`.'
                 ),
                'color':
                COLOR
            }
        }

        if command == 'list':
            helptext = [help_command['list']]
        elif command == 'help':
            helptext = [attachment for attachment in help_command.values()]
        return helptext, ''

    def _is_mongoId(self, _id):
        if len(_id) == 24:
            return True
        return False

    def list_alerts(self, command, typeof, name):
        params = {'filter': {'fixed': False}}
        valid = ['service', 'device']
        if typeof and typeof in valid:
            params['filter']['config.subjectType'] = typeof
        elif typeof == 'group':
            params['filter']['subjectGroup'] = name
        elif typeof in ['all', '']:
            pass  # don't need to do anything
        else:
            text = 'Instead of `{}` you should have used `group`, `service`, `device` or `all`'.format(
                typeof), ''
            return text

        services = self.service.list()
        devices = self.device.list()

        if name and typeof != 'group':
            _id = name if not name else self.find_id(name, services, devices)
            params['filter']['config.subjectId'] = _id

        results = self.alert.triggered(params=params)
        alerts = sorted(
            results,
            key=lambda alert: alert['config']['lastTriggeredAt']['sec'],
            reverse=True)
        if not (typeof or name):
            # When making a standard `alerts list` we want to give a limited amount of alerts.
            stripped_alerts = alerts[:5]
        else:
            # we want to keep the entire list here
            stripped_alerts = alerts
        open_alerts = []

        for alert in stripped_alerts:
            field = alert['config']['fullName'].split(' > ')
            comparison = alert['config'].get('fullComparison', '')
            value = '{}{}'.format(alert['config'].get('value', ''),
                                  alert['config'].get('units', ''))
            group = alert['config'].get('group', 'Ungrouped')
            triggered_time = time.localtime(
                alert['config']['lastTriggeredAt']['sec'])

            _id = alert['config']['subjectId']
            if self._is_mongoId(_id):
                name = self.find_name(_id, services, devices)
                name = '{}: {}'.format(alert['config']['subjectType'].title(),
                                       name)
            else:
                name = 'Group: {}'.format(_id)

            attachment = {
                'title':
                '{}'.format(name),
                'text':
                '{} {} {}'.format(field[1], comparison, value),
                'color':
                COLOR,
                'fields': [
                    {
                        'title':
                        'Last triggered',
                        'value':
                        time.strftime('%Y-%m-%d, %H:%M:%S', triggered_time)
                    },
                    # waiting on backend bugfix sd-2190
                    # {
                    #     'title': 'Group',
                    #     'value': group,
                    #     'short': True
                    # }
                ]
            }
            open_alerts.append(attachment)
        if open_alerts:
            if len(alerts) > len(stripped_alerts):
                message = (
                    'You have {} open alerts but I\'m only showing the last {},'
                    .format(len(alerts), len(stripped_alerts)) +
                    ' do `list open alerts all` to see all of them')
            else:
                message = 'Chop chop, you\'d better sort out these open alerts soon'
            return open_alerts, message
        else:
            return 'I could not find any open alerts for you.', ''
예제 #5
0
class AlertTest(BaseTest):

    @patch.object(ApiClient, '_make_request')
    def setUp(self, mock_make_request):
        self.alertobj = self.get_json('/json/alert.json')

        self.client = ApiClient('aeou')
        self.client._make_request = mock_make_request
        self.client._make_request.return_value = self.alertobj
        self.alert = Alert(api=self.client)

    def test_alert_create(self):
        data = {'data': 'alert'}
        self.alert.create(data)
        self.client._make_request.assert_called_with(
            data=data,
            method='POST',
            url=Alert.PATHS['create'],
            params=None
        )

    def test_alert_delete(self):
        self.alert.delete(1)
        self.client._make_request.assert_called_with(
            data=None,
            method='DELETE',
            url=Alert.PATHS['delete'].format(1),
            params=None
        )

    def test_alert_list(self):
        self.client._make_request.return_value = [self.alertobj]
        self.alert.list()
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['list'],
            params=None
        )

    def test_alert_update(self):
        data = {'name': 'test', 'type': 'alert'}
        self.alert.update(_id=1, data=data)
        self.client._make_request.assert_called_with(
            data=data,
            method='PUT',
            url=Alert.PATHS['update'].format(1),
            params=None
        )

    def test_alert_view(self):
        self.alert.view(1)
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['view'].format(1),
            params=None
        )

    def test_alert_triggered(self):
        self.client._make_request.return_value = [self.alertobj]
        self.alert.triggered(1, 'device', True)
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['triggered'],
            params={'filter': '{"config.subjectId": 1, "config.subjectType": "device", "fixed": true}'}
        )

    def test_alert_device_metrics(self):
        self.alert.device_metrics()
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['device_metrics'],
            params=None
        )

    def test_alert_service_metrics(self):
        self.alert.service_metrics()
        self.client._make_request.assert_called_with(
            data=None,
            method='GET',
            url=Alert.PATHS['service_metrics'],
            params=None
        )