Beispiel #1
0
    def get_usergroup_members(self, group_id):
        """
        Get the usergroup users list
        """
        datamgr = request.app.datamgr

        usergroup = datamgr.get_usergroup(group_id)
        if not usergroup:
            usergroup = datamgr.get_usergroup(search={
                'max_results': 1,
                'where': {
                    'name': group_id
                }
            })
            if not usergroup:
                return self.webui.response_invalid_parameters(
                    _('Element does not exist: %s') % group_id)

        items = []
        if not isinstance(usergroup.members, str):
            # Get element state configuration
            items_states = ElementState()

            for member in usergroup.members:
                logger.debug("Group member: %s", member)
                cfg_state = items_states.get_icon_state('user', member.status)

                items.append({
                    'id':
                    member.id,
                    'type':
                    'user',
                    'name':
                    member.name,
                    'alias':
                    member.alias,
                    'status':
                    member.status,
                    'icon':
                    'fa fa-%s item_%s' %
                    (cfg_state['icon'], cfg_state['class']),
                    'state':
                    member.get_html_state(text=None, title=member.alias),
                    'url':
                    member.get_html_link()
                })

        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(items)
Beispiel #2
0
    def get_date(self, _date, fmt=None, duration=False):
        """Format the provided `_date` as a string according to the specified format.

        If no date format is specified, it uses the one defined in the ElementState object that is
        the date format defined in the application configuration.

        If duration is True, the date is displayed as a pretty date: 1 day 12 minutes ago ...
        """
        if _date == self.__class__._default_date:
            return _('Never dated!')

        if duration:
            return Helper.print_duration(_date, duration_only=False, x_elts=0)

        item_state = ElementState()
        if not fmt:
            if item_state.date_format:
                fmt = item_state.date_format

        # Make timestamp to datetime
        _date = datetime.utcfromtimestamp(_date)
        # Tell the datetime object that it's in UTC time zone since
        # datetime objects are 'naive' by default
        _date = _date.replace(tzinfo=item_state.tz_from)
        # Convert to required time zone
        _date = _date.astimezone(item_state.tz_to)

        if fmt:
            return _date.strftime(fmt)

        return _date.isoformat(' ')
Beispiel #3
0
    def get_html_state(self,
                       extra='',
                       icon=True,
                       text='',
                       title='',
                       disabled=False,
                       object_type=None,
                       object_item=None,
                       size='',
                       use_status=None):
        # pylint: disable=too-many-arguments
        """Uses the ElementState singleton to display HTML state for an item"""
        if self.type.startswith(
                'check.result') and self.logcheckresult != 'logcheckresult':
            return ElementState().get_html_state('logcheckresult',
                                                 self.logcheckresult, extra,
                                                 icon, text, title, disabled)

        return super(History, self).get_html_state(object_type=self.get_type(),
                                                   object_item=self,
                                                   extra=extra,
                                                   icon=icon,
                                                   text=text,
                                                   title=title,
                                                   disabled=disabled,
                                                   size=size)
    def get_group_members(self, group_id):
        """
        Get the servicegroup services list
        """
        datamgr = request.app.datamgr

        servicegroup = datamgr.get_servicegroup(group_id)
        if not servicegroup:
            servicegroup = datamgr.get_servicegroup(
                search={'max_results': 1, 'where': {'name': group_id}}
            )
            if not servicegroup:
                return self.webui.response_invalid_parameters(_('Element does not exist: %s')
                                                              % group_id)

        items = []
        if not isinstance(servicegroup.members, str):
            # Get element state configuration
            items_states = ElementState()

            for member in servicegroup.members:
                logger.debug("Group member: %s", member)
                cfg_state = items_states.get_icon_state('service', member.status)

                items.append({
                    'id': member.id,
                    'type': 'service',
                    'name': "%s/%s" % (member.host.name, member.name),
                    'alias': "%s/%s" % (member.host.alias, member.alias),
                    'status': member.status,
                    'icon': 'fa fa-%s item_%s' % (cfg_state['icon'], cfg_state['class']),
                    'state': member.get_html_state(text=None, title=member.alias),
                    'url': member.get_html_link()
                })

        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(items)
Beispiel #5
0
    def test_items_states(self):
        """ Items - states """

        items_states = ElementState()
        assert items_states.object_types_states
        assert items_states.default_states
        assert items_states.states
        print("Objects types and states", items_states.object_types_states)
        print("Default states", items_states.default_states)
        print("Items states", items_states.states)

        for s in self.config:
            print(s)
            s = s.split('.')
            if s[0] not in ['items', 'bottle'] and len(s) > 1:
                assert s[1] not in items_states.object_types_states
                assert s[1] not in items_states.default_states
                assert s[1] not in items_states.states
            else:
                if s[0] not in ['items']:
                    continue
                print(s)
                if s[1] == 'item':
                    assert s[1] not in items_states.object_types_states
                    assert s[1] not in items_states.states
                    if len(s) > 2:
                        assert s[2] in items_states.default_states
                else:
                    assert s[1] not in items_states.default_states

                    if s[1] in ['content', 'back', 'front', 'badge']:
                        assert s[1] not in items_states.object_types_states
                        assert s[1] not in items_states.states
                        continue

                    assert s[1] in items_states.object_types_states
                    assert s[1] in items_states.states

                    if len(s) > 2:
                        assert s[2] in items_states.object_types_states[s[1]]
                        assert s[2] in items_states.states[s[1]]
                        print(s[1], items_states.states[s[1]])
Beispiel #6
0
    def get_html_state(self,
                       extra='',
                       icon=True,
                       text='',
                       title='',
                       disabled=False,
                       object_type=None,
                       object_item=None,
                       size='',
                       use_status=None):
        # pylint: disable=too-many-arguments
        """Uses the ElementState singleton to display HTML state for an item"""
        if not object_type:
            object_type = self.object_type

        if not object_item:
            object_item = self

        if not self.is_template:
            return ElementState().get_html_state(object_type, object_item,
                                                 extra, icon, text, title,
                                                 disabled, size, use_status)

        return self.get_html_link(title=title)
Beispiel #7
0
    def get_realm_members(self, element_id):
        """Get the realm hosts list"""
        datamgr = request.app.datamgr

        realm = datamgr.get_realm(element_id)
        if not realm:
            realm = datamgr.get_realm(search={
                'max_results': 1,
                'where': {
                    'name': element_id
                }
            })
            if not realm:
                return self.webui.response_invalid_parameters(
                    _('Element does not exist: %s') % element_id)

        # Get elements from the data manager
        search = {
            'where': {
                '_realm': realm.id
            },
            'sort': '-business_impact, -ls_state_id, -ls_last_state_changed'
        }
        hosts = datamgr.get_hosts(search=search)
        logger.debug("get_realm_members, search: %s, found %d hosts", search,
                     len(hosts))

        # Get element state configuration
        items_states = ElementState()

        items = []
        items.append({
            'id':
            -1,
            'type':
            'host',
            'tr':
            """
                <table class="table table-invisible table-condensed">
                  <thead><tr>
                    <th></th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                  </tr></thead>

                  <tbody>
                  </tbody>
                </table>
            """ %
            (_("BI"), _("Element"), _("Since"), _("Last check"), _("Output"))
        })
        for member in hosts:
            logger.debug("Realm member: %s", member)
            cfg_state = items_states.get_icon_state('host', member.status)

            tr = """<tr>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td class="hidden-xs">%s</td>
                <td class="hidden-xs">%s</td>
                <td class="hidden-sm hidden-xs">%s: %s</td>
            </tr>""" % (member.get_html_state(text=None, title=member.alias),
                        Helper.get_html_business_impact(
                            member.business_impact, icon=True,
                            text=False), member.get_html_link(),
                        Helper.print_duration(member.last_state_changed,
                                              duration_only=True,
                                              x_elts=2),
                        Helper.print_duration(
                            member.last_check, duration_only=True, x_elts=2),
                        Helper.print_date(member.last_check), member.output)
            items.append({
                'id':
                member.id,
                'type':
                'host',
                'name':
                member.name,
                'alias':
                member.alias,
                'status':
                member.status,
                'icon':
                'fa fa-%s item_%s' % (cfg_state['icon'], cfg_state['class']),
                'state':
                member.get_html_state(text=None, title=member.alias),
                'tr':
                tr
            })

        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(items)
    def get_realm_members(self, element_id):
        """Get the realm hosts list"""
        datamgr = request.app.datamgr

        realm = datamgr.get_realm(element_id)
        if not realm:
            realm = datamgr.get_realm(search={'max_results': 1, 'where': {'name': element_id}})
            if not realm:
                return self.webui.response_invalid_parameters(_('Element does not exist: %s')
                                                              % element_id)

        # Get elements from the data manager
        search = {
            'where': {'_realm': realm.id},
            'sort': '-business_impact, -ls_state_id, -ls_last_state_changed'
        }
        hosts = datamgr.get_hosts(search=search)
        logger.debug("get_realm_members, search: %s, found %d hosts", search, len(hosts))

        # Get element state configuration
        items_states = ElementState()

        items = []
        items.append({
            'id': -1,
            'type': 'host',
            'tr': """
                <table class="table table-invisible table-condensed">
                  <thead><tr>
                    <th></th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                    <th>%s</th>
                  </tr></thead>

                  <tbody>
                  </tbody>
                </table>
            """ % (
                _("BI"), _("Element"),
                _("Since"), _("Last check"), _("Output")
            )
        })
        for member in hosts:
            logger.debug("Realm member: %s", member)
            cfg_state = items_states.get_icon_state('host', member.status)

            tr = """<tr>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td class="hidden-xs">%s</td>
                <td class="hidden-xs">%s</td>
                <td class="hidden-sm hidden-xs">%s: %s</td>
            </tr>""" % (
                member.get_html_state(text=None, title=member.alias),
                Helper.get_html_business_impact(member.business_impact, icon=True, text=False),
                member.get_html_link(),
                Helper.print_duration(member.last_state_changed, duration_only=True, x_elts=2),
                Helper.print_duration(member.last_check, duration_only=True, x_elts=2),
                Helper.print_date(member.last_check),
                member.output
            )
            items.append({
                'id': member.id,
                'type': 'host',
                'name': member.name,
                'alias': member.alias,
                'status': member.status,
                'icon': 'fa fa-%s item_%s' % (cfg_state['icon'], cfg_state['class']),
                'state': member.get_html_state(text=None, title=member.alias),
                'tr': tr
            })

        response.status = 200
        response.content_type = 'application/json'
        return json.dumps(items)
Beispiel #9
0
    def test_03_html_states(self):
        print("---")

        items_states = ElementState()
        assert items_states.object_types_states
        assert items_states.default_states
        assert items_states.states

        # Objects known states
        save_object_type = 'user'
        for object_type in items_states.object_types_states:
            print("Html for: ", object_type)
            for state in items_states.get_icon_states(object_type):
                if state == 'state_view':
                    continue

                elt = BackendElement({'_id': '0', 'status': state})
                print("Html for:", object_type, ", object:", elt)
                assert items_states.get_html_state(object_type, elt)
                print("Html : ", items_states.get_html_state(object_type, elt))

        # Unknown states
        print("States for: fake")
        print(items_states.get_icon_states('fake'))
        assert not items_states.get_icon_states('fake')

        print("Html for:", save_object_type, ", state: fake")
        print("Unknown state")
        elt = BackendElement({'_id': '0', 'status': 'fake'})
        print(items_states.get_html_state(save_object_type, elt))
        assert items_states.get_html_state(save_object_type,
                                           elt) == 'n/a - status: fake'

        print("Html for: fake, state: unknown")
        print("Unknown object type")
        elt = BackendElement({'_id': '0', 'status': 'unknown'})
        # Unknown object_type provides a default user html state ...
        item_state = items_states.get_html_state('fake', elt)
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="fake"><span class="fa-stack"  title="User default text"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>User default text</span></div>'''
            % elt.id)

        # Bad parameters
        print("No icon/text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=False,
                                                 text='')
        print(item_state)
        self.assertEqual(item_state, 'n/a - icon/text')

        print("Default icon/text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text='')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="User default text"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>User default text</span></div>'''
            % elt.id)

        # Other parameters
        print("Default icon/text - disabled")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text='',
                                                 disabled=True)
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state text-muted " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="User default text"><i class="fa fa-circle fa-stack-2x text-muted"></i><i class="fa fa-user fa-stack-1x "></i></span><span>User default text</span></div>'''
            % elt.id)

        print("Default icon/text - title and default text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 title='Test title')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="Test title"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>User default text</span></div>'''
            % elt.id)

        print("Default icon/text - title without text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text=None,
                                                 title='Test title')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="Test title"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span></span></div>'''
            % elt.id)

        print("Default icon/text - not title and default text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text='Test')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="User default text"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>Test</span></div>'''
            % elt.id)

        print("Default icon/text - not title and text")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text='Test text')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack"  title="User default text"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>Test text</span></div>'''
            % elt.id)

        print("Default icon/text - extra")
        item_state = items_states.get_html_state(save_object_type,
                                                 elt,
                                                 icon=True,
                                                 text='',
                                                 extra='test')
        print(item_state)
        self.assertEqual(
            item_state,
            '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user"><span class="fa-stack" style="opacity: 0.7" title="User default texttest"><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x "></i></span><span>User default texttest</span></div>'''
            % elt.id)
Beispiel #10
0
    def test_02_items_states(self):
        print("---")

        items_states = ElementState()
        assert items_states.object_types_states
        assert items_states.default_states
        assert items_states.states
        print("Objects types and states", items_states.object_types_states)
        print("Default states", items_states.default_states)
        print("Items states", items_states.states)

        assert items_states.get_objects_types()
        print("All objects types : ", items_states.get_objects_types())

        assert items_states.get_icon_states()
        print("All objects : ", items_states.get_icon_states())

        assert items_states.get_default_states()
        print("Default states : ", items_states.get_default_states())

        # Objects known states
        for object_type in items_states.object_types_states:
            assert items_states.get_icon_states(object_type)
            print(object_type, ", all states: ",
                  items_states.get_icon_states(object_type))
            for state in items_states.get_icon_states(object_type):
                assert items_states.get_icon_state(object_type, state)
                print(object_type, ", state: ", state, ": ",
                      items_states.get_icon_state(object_type, state))

        assert not items_states.get_icon_state(None, None)

        # Default states are in all objects types
        for state in items_states.get_default_states():
            print("Default state: ", state)
            for object_type in items_states.object_types_states:
                assert items_states.get_icon_states(object_type)
    def test_html_states(self):
        """ Items - HTML states """

        self.maxDiff = None

        items_states = ElementState()
        assert items_states.object_types_states
        assert items_states.default_states
        assert items_states.states

        # Objects known states
        save_object_type = 'user'
        for object_type in items_states.object_types_states:
            print("Html for: ", object_type)
            for state in items_states.get_icon_states(object_type):
                if state == 'state_view':
                    continue

                elt = BackendElement({
                    '_id': '0', 'status': state
                })
                print("Html for:", object_type, ", object:", elt)
                assert items_states.get_html_state(object_type, elt)
                print("Html : ", items_states.get_html_state(object_type, elt))

        # Unknown states
        print("States for: fake")
        print(items_states.get_icon_states('fake'))
        assert not items_states.get_icon_states('fake')

        print("Html for:", save_object_type, ", state: fake")
        print("Unknown state")
        elt = BackendElement({
            '_id': '0', 'status': 'fake'
        })
        print(items_states.get_html_state(save_object_type, elt))
        assert items_states.get_html_state(save_object_type, elt) == 'n/a - status: fake'

        print("Html for: fake, state: unknown")
        print("Unknown object type")
        elt = BackendElement({
            '_id': '0', 'status': 'unknown'
        })
        # Unknown object_type provides a default user html state ...
        item_state = items_states.get_html_state('fake', elt)
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="fake" data-item-state="" title=""><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id

        # Bad parameters
        print("No icon/text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=False, text='')
        print(item_state)
        assert item_state == 'n/a - icon/text'

        print("Default icon/text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True, text='')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title=""><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id

        # Other parameters
        print("Default icon/text - disabled")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True, text='',
                                                 disabled=True)
        print(item_state)
        assert item_state == \
                         '''<div class="item-state text-muted " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title=""><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x text-muted"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id

        print("Default icon/text - title and default text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True,
                                                 title='Test title')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title="Test title"><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id

        print("Default icon/text - title without text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True, text=None,
                                                 title='Test title')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title="Test title"><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id

        print("Default icon/text - not title and default text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True, text='Test')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title=""><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span>Test</span></div>''' % elt.id

        print("Default icon/text - not title and text")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True,
                                                 text='Test text')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title=""><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span>Test text</span></div>''' % elt.id

        print("Default icon/text - extra")
        item_state = items_states.get_html_state(save_object_type, elt, icon=True, text='',
                                                 extra='test')
        print(item_state)
        assert item_state == \
                         '''<div class="item-state item_user " style="display: inline; font-size:0.9em;" data-item-id="%s" data-item-name="anonymous" data-item-type="user" data-item-state="" title="testtest"><span class="fa-stack " ><i class="fa fa-circle fa-stack-2x item_user"></i><i class="fa fa-user fa-stack-1x fa-inverse"></i></span><span></span></div>''' % elt.id
    def test_items_states_2(self):
        """ Items - states (2) """

        items_states = ElementState()
        assert items_states.object_types_states
        assert items_states.default_states
        assert items_states.states
        print("Objects types and states", items_states.object_types_states)
        print("Default states", items_states.default_states)
        print("Items states", items_states.states)

        assert items_states.get_objects_types()
        print("All objects types : ", items_states.get_objects_types())

        assert items_states.get_icon_states()
        print("All objects : ", items_states.get_icon_states())

        assert items_states.get_default_states()
        print("Default states : ", items_states.get_default_states())

        # Objects known states
        for object_type in items_states.object_types_states:
            assert items_states.get_icon_states(object_type)
            print(object_type, ", all states: ", items_states.get_icon_states(object_type))
            for state in items_states.get_icon_states(object_type):
                assert items_states.get_icon_state(object_type, state)
                print(object_type, ", state: ", state, ": ", items_states.get_icon_state(
                    object_type, state))

        assert not items_states.get_icon_state(None, None)

        # Default states are in all objects types
        for state in items_states.get_default_states():
            print("Default state: ", state)
            for object_type in items_states.object_types_states:
                assert items_states.get_icon_states(object_type)
Beispiel #13
0
    def table_data(self, plugin_table):
        # Because there are many locals needed :)
        # pylint: disable=too-many-locals
        """Return elements data in json format as of Datatables SSP protocol

        More info: https://datatables.net/manual/server-side

        Example URL::

            POST /?
            draw=1&
            columns[0][data]=alias&
            columns[0][name]=&
            columns[0][searchable]=true&
            columns[0][orderable]=true&
            columns[0][search][value]=&
            columns[0][search][regex]=false&
             ...
            order[0][column]=0&
            order[0][dir]=asc&
            start=0&
            length=10&
            search[value]=&
            search[regex]=false&

        Request parameters are Json formatted

        Request Parameters:
        - object_type: object type managed by the datatable
        - links: url prefix to be used by the links in the table
        - embedded: true / false whether the table is embedded by an external application
            **Note**: those three first parameters are not datatable specific parameters :)

        - draw, index parameter to be returned in the response

            Pagination:
            - start / length, for pagination

            Searching:
            - search (value or regexp)
            search[value]: Global search value. To be applied to all columns which are searchable
            search[regex]: true if search[value] is a regex

            Sorting:
            - order[i][column] / order[i][dir]
            index of the columns to order and sort direction (asc/desc)

            Columns:
            - columns[i][data]: Column's data source, as defined by columns.data.
            - columns[i][name]: Column's name, as defined by columns.name.
            - columns[i][searchable]: Flag to indicate if this column is searchable (true).
            - columns[i][orderable]: Flag to indicate if this column is orderable (true).
            - columns[i][search][value]: Search value to apply to this specific column.
            - columns[i][search][regex]: Flag to indicate if the search term for this column is a
            regex.

        Response data:
        - draw

        - recordsTotal: total records, before filtering
            (i.e. total number of records in the database)

        - recordsFiltered: Total records, after filtering
            (i.e. total number of records after filtering has been applied -
            not just the number of records being returned for this page of data).

        - data: The data to be displayed in the table.
            an array of data source objects, one for each row, which will be used by DataTables.

        - error (optional): Error message if an error occurs
            Not included if there is no error.
        """
        # Manage request parameters ...
        logger.info("request data for table: %s, templates: %s",
                    request.forms.get('object_type'), self.templates)

        # Because of specific datatables parameters name (eg. columns[0] ...)
        # ... some parameters have been json.stringify on client side !
        params = {}
        for key in list(request.params.keys()):
            if key in ['columns', 'order', 'search']:
                params[key] = json.loads(request.params.get(key))
            else:
                params[key] = request.params.get(key)
        # params now contains 'valid' query parameters as we should have found them ...
        logger.debug("table request parameters: %s", params)

        parameters = {}

        # Manage page number ...
        # start is the first requested row and we must transform to a page count ...
        first_row = int(params.get('start', '0'))
        # length is the number of requested rows
        rows_count = int(params.get('length', '25'))

        parameters['page'] = (first_row // rows_count) + 1
        parameters['max_results'] = rows_count
        logger.debug("get %d rows from row #%d -> page: %d", rows_count,
                     first_row, parameters['page'])

        # Columns ordering
        # order:[{"column":2,"dir":"desc"}]
        if 'order' in params and 'columns' in params and params['order']:
            sorted_columns = []
            for order in params['order']:
                idx = int(order['column'])
                if params['columns'][idx] and params['columns'][idx]['data']:
                    logger.debug("sort by column %d (%s), order: %s ", idx,
                                 params['columns'][idx]['data'], order['dir'])
                    if order['dir'] == 'desc':
                        sorted_columns.append('-' +
                                              params['columns'][idx]['data'])
                    else:
                        sorted_columns.append(params['columns'][idx]['data'])
            if sorted_columns:
                parameters['sort'] = ','.join(sorted_columns)

            logger.info("backend order request parameters: %s", parameters)

        # Individual column search parameter
        s_columns = []
        if 'columns' in params and params['columns']:
            for column in params['columns']:
                if 'searchable' not in column or 'search' not in column:  # pragma: no cover
                    continue
                if 'value' not in column[
                        'search'] or not column['search']['value']:
                    continue
                logger.debug("search column '%s' for '%s'", column['data'],
                             column['search']['value'])

                for field in self.table_columns:
                    if field['data'] != column['data']:
                        continue

                    # Some specific types...
                    if field['type'] == 'boolean':
                        s_columns.append({
                            column['data']:
                            column['search']['value'] == 'true'
                        })
                    elif field['type'] == 'integer':
                        s_columns.append(
                            {column['data']: int(column['search']['value'])})
                    elif field['format'] == 'select':
                        values = column['search']['value'].split(',')
                        if len(values) > 1:
                            s_columns.append({column['data']: {"$in": values}})
                        else:
                            s_columns.append({column['data']: values[0]})
                    # ... the other fields :)
                    else:
                        # Do not care about 'smart' and 'caseInsensitive' boolean parameters ...
                        if column['search']['regex']:
                            s_columns.append({
                                column['data']: {
                                    "$regex":
                                    ".*" + column['search']['value'] + ".*"
                                }
                            })
                        else:
                            s_columns.append(
                                {column['data']: column['search']['value']})
                    break

            logger.info("backend search individual columns parameters: %s",
                        s_columns)

        # Global search parameter
        # search:{"value":"test","regex":false}
        s_global = {}
        # pylint: disable=too-many-nested-blocks
        # Will be too complex else ...
        if 'search' in params and 'columns' in params and params['search']:
            # params['search'] contains something like: {u'regex': False, u'value': u'name:pi1'}
            # global regex is always ignored ... in favor of the column declared regex
            logger.info("global search requested: %s ", params['search'])
            if 'value' in params['search'] and params['search']['value']:
                # There is something to search for...
                logger.debug("search requested, value: %s ",
                             params['search']['value'])

                # New strategy: decode search patterns...
                search = Helper.decode_search(params['search']['value'],
                                              plugin_table)
                logger.info("decoded search pattern: %s", search)

                # Old strategy: search for the value in all the searchable columns...
                # if not search:
                #     logger.info("applying datatable search pattern...")
                #     for column in params['columns']:
                #         if not column['searchable']:
                #             continue
                #         logger.debug("search global '%s' for '%s'",
                #                      column['data'], params['search']['value'])
                #         if 'regex' in params['search']:
                #             if params['search']['regex']:
                #                 s_global.update(
                #                     {column['data']: {
                #                         "$regex": ".*" + params['search']['value'] + ".*"}})
                #             else:
                #                 s_global.update({column['data']: params['search']['value']})
                s_global = search

            logger.info("backend search global parameters: %s", s_global)

        # Specific hack to filter the log check results that are not dated!
        if self.object_type == 'logcheckresult':
            s_columns.append({"last_check": {"$ne": 0}})

        if s_columns and s_global:
            parameters['where'] = {"$and": [{"$and": s_columns}, s_global]}
        elif s_columns:
            parameters['where'] = {"$and": s_columns}
        elif s_global:
            parameters['where'] = s_global

        # Embed linked resources / manage templated resources
        parameters['embedded'] = {}
        for field in self.embedded:
            parameters['embedded'].update({field: 1})

        logger.debug("backend embedded parameters: %s", parameters['embedded'])

        # Count total elements excluding templates if necessary
        if self.is_templated:
            if self.ui_visibility:
                self.records_total = self.datamgr.my_backend.count(
                    self.object_type,
                    params={
                        'where': {
                            '_is_template': self.templates,
                            'webui_visible': True
                        }
                    })
            else:
                self.records_total = self.datamgr.my_backend.count(
                    self.object_type,
                    params={'where': {
                        '_is_template': self.templates
                    }})
            if 'where' in parameters:
                parameters['where'].update({'_is_template': self.templates})
            else:
                parameters['where'] = {'_is_template': self.templates}
        else:
            if self.ui_visibility:
                self.records_total = self.datamgr.my_backend.count(
                    self.object_type,
                    params={'where': {
                        'webui_visible': True
                    }})
            else:
                self.records_total = self.datamgr.my_backend.count(
                    self.object_type)

        if self.ui_visibility:
            if 'where' in parameters:
                parameters['where'].update({'webui_visible': True})
            else:
                parameters['where'] = {'webui_visible': True}

        # Request objects from the backend ...
        logger.info("table data get parameters: %s", parameters)
        items = self.datamgr.my_backend.get(self.object_type,
                                            params=parameters)
        logger.info("table data got %d items", len(items))
        if not items:
            logger.info("No backend elements match search criteria: %s",
                        parameters)
            # Empty response
            return json.dumps({
                # draw is the request number ...
                "draw": int(params.get('draw', '0')),
                "recordsTotal": 0,
                "recordsFiltered": 0,
                "data": []
            })

        # Create an object ...
        object_class = [
            kc for kc in self.datamgr.known_classes
            if kc.get_type() == self.object_type
        ]
        if not object_class:  # pragma: no cover, should never happen!
            logger.warning("datatable, unknown object type: %s",
                           self.object_type)
            # Empty response
            return json.dumps({
                # draw is the request number ...
                "draw": int(params.get('draw', '0')),
                "recordsTotal": 0,
                "recordsFiltered": 0,
                "data": []
            })

        # Update table inner properties with the object class defined properties
        object_class = object_class[0]

        self.id_property = '_id'
        if hasattr(object_class, 'id_property'):
            self.id_property = object_class.id_property
        self.name_property = 'name'
        if hasattr(object_class, 'name_property'):
            self.name_property = object_class.name_property
        self.status_property = 'status'
        if hasattr(object_class, 'status_property'):
            self.status_property = object_class.status_property
        logger.debug(
            "datatable, object type: '%s' and properties: %s / %s / %s",
            object_class, self.id_property, self.name_property,
            self.status_property)

        # Change item content...
        rows = []
        # Total number of filtered records
        self.records_filtered = self.records_total
        for item in items:
            bo_object = object_class(item)
            if not bo_object.ui_visible:
                logger.debug("Not UI visible object: %s", bo_object)
                continue

            logger.info("table data object: %s", bo_object)
            logger.debug("table data object: %s", bo_object)
            # This is an awful hack that allows to update the objects filtered for a table.
            # Two main interests:
            # - update the backend because some massive modifications are necessary for testing
            # - prepare a massive update feature in the Web UI :)
            # -----
            # if self.is_templated and self.templates and self.object_type == 'service':
            #     logger.warning("service template: %s for host: %s",
            #                    bo_object.name, bo_object['host'])
            #     if bo_object['host'].name.startswith('fdj'):
            #         logger.info("To be updated...")
            #         data = {
            #             "check_freshness": True,
            #             "freshness_threshold": 86400,
            #             "passive_checks_enabled": True,
            #             "active_checks_enabled": False
            #         }
            #         result = self.datamgr.update_object(element=bo_object, data=data)
            #         if result is True:
            #             logger.info("updated.")
            #         else:
            #             logger.error("update failed!")
            # -----

            # Each item contains the total number of records matching the search filter
            self.records_filtered = item['_total']

            row = {}
            row['DT_RowData'] = {}
            row['_id'] = bo_object.id
            for field in self.table_columns:
                logger.debug(" - field: %s", field)
                # Specific fields
                if field['data'] == self.name_property:
                    # Create a link to navigate to the item page
                    row[self.name_property] = bo_object.html_link
                    # Store the item name in a specific field of the row.
                    # The value will be retrieved by the table actions (ack, recheck, ...)
                    row['DT_RowData'].update(
                        {"object_%s" % self.object_type: bo_object.name})
                    continue

                if field['data'] == self.status_property:
                    # Replace the text status with the specific item HTML state
                    row[self.status_property] = bo_object.get_html_state(
                        text=None, title=bo_object.status)
                    # Use the item status to specify the table row class
                    # row['DT_RowClass'] = "table-row-%s" % (bo_object.status.lower())
                    continue

                if field['data'] in [
                        '_overall_state_id', 'overall_state', 'overall_status'
                ]:
                    # Get the item overall state from the data manager
                    f_get_overall_state = getattr(
                        self.datamgr,
                        'get_%s_overall_state' % self.object_type)
                    if f_get_overall_state:
                        (dummy,
                         overall_status) = f_get_overall_state(bo_object)

                        # Get element state configuration
                        row[field['data']] = ElementState().get_html_state(
                            self.object_type,
                            bo_object,
                            text=None,
                            title=bo_object.overall_state_to_title[
                                bo_object.overall_state],
                            use_status=overall_status)
                        # Use the item overall state to specify the table row class
                        row['DT_RowClass'] = "table-row-%s" % (overall_status)
                    else:  # pragma: no cover, should never happen!
                        logger.warning(
                            "Missing get_overall_state method for: %s",
                            self.object_type)
                        row[field['data']] = 'XxX'
                    continue

                if "business_impact" in field['data']:
                    # Replace the BI count with the specific item HTML formatting
                    row[field['data']] = Helper.get_html_business_impact(
                        bo_object.business_impact)
                    continue

                # Specific fields type
                if field['type'] == 'datetime' or field['format'] == 'datetime':
                    # Replace the timestamp with the formatted date
                    row[field['data']] = bo_object.get_date(
                        bo_object[field['data']])
                    continue

                if field['type'] == 'boolean':
                    # Replace the boolean vaue with the specific item HTML formatting
                    row[field['data']] = Helper.get_on_off(
                        bo_object[field['data']])
                    continue

                if field['type'] == 'list':
                    # Replace the list with the specific list HTML formatting
                    if hasattr(bo_object, field['data']):
                        row[field['data']] = Helper.get_html_item_list(
                            bo_object.id,
                            field['data'],
                            getattr(bo_object, field['data']),
                            title=field['title'])
                    else:
                        row[field['data']] = 'Unknown'
                    continue

                if field['type'] == 'dict':
                    # Replace the dictionary with the specific dict HTML formatting
                    row[field['data']] = Helper.get_html_item_list(
                        bo_object.id,
                        field['data'],
                        getattr(bo_object, field['data']),
                        title=field['title'])
                    continue

                if field['type'] == 'objectid':
                    if isinstance(bo_object[field['data']], BackendElement):
                        row[field['data']] = bo_object[
                            field['data']].get_html_link(
                                prefix=request.params.get('links'))
                        # row['DT_RowData'].update({
                        #     "object_%s" % field['data']: bo_object[field['data']].name
                        # })
                    else:
                        logger.warning(
                            "Table field is supposed to be an object: %s, %s = %s",
                            bo_object.name, field['data'],
                            getattr(bo_object, field['data']))
                        row[field['data']] = getattr(bo_object, field['data'])
                        if row[field['data']] == field['resource']:
                            row[field['data']] = '...'
                    continue

                # For any non-specific fields, send the field value to the table
                row[field['data']] = getattr(bo_object, field['data'], 'unset')
                logger.debug(" -> field: %s", field)
            logger.debug("table data row: %s", row)

            # logger.debug("Table row: %s", row)
            rows.append(row)

        logger.debug("filtered records: %d out of total: %d",
                     self.records_filtered, self.records_total)

        # Send response
        return json.dumps({
            "draw": int(float(params.get('draw', '0'))),
            "recordsTotal": self.records_total,
            "recordsFiltered": self.records_filtered,
            "data": rows
        })