예제 #1
0
def mock_puppetdb_default_nodes(mocker):
    node_list = [
        Node('_', 'node-unreported',
             report_timestamp='2013-08-01T09:57:00.000Z',
             latest_report_hash='1234567',
             catalog_timestamp='2013-08-01T09:57:00.000Z',
             facts_timestamp='2013-08-01T09:57:00.000Z',
             status_report='unreported'),
        Node('_', 'node-changed',
             report_timestamp='2013-08-01T09:57:00.000Z',
             latest_report_hash='1234567',
             catalog_timestamp='2013-08-01T09:57:00.000Z',
             facts_timestamp='2013-08-01T09:57:00.000Z',
             status_report='changed'),
        Node('_', 'node-failed',
             report_timestamp='2013-08-01T09:57:00.000Z',
             latest_report_hash='1234567',
             catalog_timestamp='2013-08-01T09:57:00.000Z',
             facts_timestamp='2013-08-01T09:57:00.000Z',
             status_report='failed'),
        Node('_', 'node-noop',
             report_timestamp='2013-08-01T09:57:00.000Z',
             latest_report_hash='1234567',
             catalog_timestamp='2013-08-01T09:57:00.000Z',
             facts_timestamp='2013-08-01T09:57:00.000Z',
             status_report='noop'),
        Node('_', 'node-unchanged',
             report_timestamp='2013-08-01T09:57:00.000Z',
             latest_report_hash='1234567',
             catalog_timestamp='2013-08-01T09:57:00.000Z',
             facts_timestamp='2013-08-01T09:57:00.000Z',
             status_report='unchanged'),
    ]
    return mocker.patch.object(app.puppetdb, 'nodes',
                               return_value=iter(node_list))
예제 #2
0
 def test_with_cached_catalog_status(self):
     node1 = Node('_', 'node', cached_catalog_status='explicitly_requested')
     node2 = Node('_', 'node', cached_catalog_status='on_failure')
     node3 = Node('_', 'node', cached_catalog_status='not_used')
     assert node1.name == 'node'
     assert node1.cached_catalog_status == 'explicitly_requested'
     assert node2.name == 'node'
     assert node2.cached_catalog_status == 'on_failure'
     assert node3.name == 'node'
     assert node3.cached_catalog_status == 'not_used'
예제 #3
0
파일: v2.py 프로젝트: johnhsieh/pypuppetdb
    def nodes(self, name=None, query=None):
        """Query for nodes by either name or query. If both aren't
        provided this will return a list of all nodes.

        :param name: (optional)
        :type name: :obj:`None` or :obj:`string`
        :param query: (optional)
        :type query: :obj:`None` or :obj:`string`

        :returns: A generator yieling Nodes.
        :rtype: :class:`pypuppetdb.types.Node`
        """

        nodes = self._query('nodes', path=name, query=query)
        # If we happen to only get one node back it
        # won't be inside a list so iterating over it
        # goes boom. Therefor we wrap a list around it.
        if type(nodes) == dict:
            log.debug("Request returned a single node.")
            nodes = [
                nodes,
            ]

        for node in nodes:
            yield Node(
                self,
                node['name'],
                deactivated=node['deactivated'],
                report_timestamp=node['report_timestamp'],
                catalog_timestamp=node['catalog_timestamp'],
                facts_timestamp=node['facts_timestamp'],
            )
예제 #4
0
    def test_apiv4_with_unchanged_status(self):
        node = Node(
            '_',
            'node',
            status='unchanged',
            report_environment='development',
            catalog_environment='development',
            facts_environment='development',
            report_timestamp='2013-08-01T09:57:00.000Z',
            catalog_timestamp='2013-08-01T09:57:00.000Z',
            facts_timestamp='2013-08-01T09:57:00.000Z',
        )

        assert node.name == 'node'
        assert node.deactivated is False
        assert node.expired is False
        assert node.report_environment == 'development'
        assert node.catalog_environment == 'development'
        assert node.facts_environment == 'development'
        assert node.report_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.facts_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.catalog_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.status == 'unchanged'
        assert str(node) == str('node')
        assert unicode(node) == unicode('node')
        assert repr(node) == str('<Node: node>')
예제 #5
0
    def test_apiv4_with_failed_noop_status(self):
        node = Node(
            '_',
            'node',
            status_report='failed',
            noop=True,
            noop_pending=False,
            report_environment='development',
            catalog_environment='development',
            facts_environment='development',
            report_timestamp='2013-08-01T09:57:00.000Z',
            catalog_timestamp='2013-08-01T09:57:00.000Z',
            facts_timestamp='2013-08-01T09:57:00.000Z',
        )

        assert node.name == 'node'
        assert node.deactivated is False
        assert node.expired is False
        assert node.report_environment == 'development'
        assert node.catalog_environment == 'development'
        assert node.facts_environment == 'development'
        assert node.report_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.facts_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.catalog_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.status == 'failed'
        assert str(node) == str('node')
        assert str(node) == str('node')
        assert repr(node) == str('<Node: node>')
예제 #6
0
    def test_with_status_unreported(self):
        node = Node(
            '_',
            'node',
            report_timestamp='2013-08-01T09:57:00.000Z',
            catalog_timestamp='2013-08-01T09:57:00.000Z',
            facts_timestamp='2013-08-01T09:57:00.000Z',
            status='unreported',
            unreported_time='0d 5h 20m',
        )

        assert node.name == 'node'
        assert node.deactivated is False
        assert node.expired is False
        assert node.report_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.facts_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.catalog_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.status is 'unreported'
        assert node.unreported_time is '0d 5h 20m'
        assert str(node) == str('node')
        assert unicode(node) == unicode('node')
        assert repr(node) == str('<Node: node>')
예제 #7
0
 def test_expired(self):
     node = Node(
         '_',
         'node',
         expired='2013-08-01T09:57:00.000Z',
     )
     assert node.name == 'node'
     assert node.expired == json_to_datetime('2013-08-01T09:57:00.000Z')
     assert str(node) == str('node')
     assert unicode(node) == unicode('node')
     assert repr(node) == str('<Node: node>')
예제 #8
0
    def nodes(self,
              unreported=2,
              with_status=False,
              with_event_numbers=True,
              **kwargs):
        """Query for nodes by either name or query. If both aren't
        provided this will return a list of all nodes. This method
        also (optionally) fetches the nodes status and (optionally)
        event counts of the latest report from puppetdb.

        :param with_status: (optional) include the node status in the\
                           returned nodes
        :type with_status: :bool:
        :param unreported: (optional) amount of hours when a node gets
                           marked as unreported
        :type unreported: :obj:`None` or integer
        :param with_event_numbers: (optional) include the exact number of\
                           changed/unchanged/failed/noop events when\
                           with_status is set to True. If set to False
                           only "some" string is provided if there are
                           resources with such status in the last report.
                           This provides performance benefits as potentially
                           slow event-counts query is omitted completely.
        :type with_event_numbers: :bool:
        :param \*\*kwargs: The rest of the keyword arguments are passed
                           to the _query function

        :returns: A generator yieling Nodes.
        :rtype: :class:`pypuppetdb.types.Node`
        """
        nodes = self._query('nodes', **kwargs)
        now = datetime.utcnow()

        # If we happen to only get one node back it
        # won't be inside a list so iterating over it
        # goes boom. Therefor we wrap a list around it.
        if type(nodes) == dict:
            nodes = [
                nodes,
            ]

        latest_events = None
        if with_status and with_event_numbers:
            latest_events = self._query(
                'event-counts',
                query=EqualsOperator("latest_report?", True),
                summarize_by='certname',
            )

        for node in nodes:
            yield Node.create_from_dict(self, node, with_status,
                                        with_event_numbers, latest_events, now,
                                        unreported)
예제 #9
0
 def test_deactivated(self):
     node = Node(
         '_',
         'node',
         deactivated='2013-08-01T09:57:00.000Z',
     )
     assert node.name == 'node'
     assert node.deactivated == \
         json_to_datetime('2013-08-01T09:57:00.000Z')
     assert str(node) == str('node')
     assert str(node) == str('node')
     assert repr(node) == str('<Node: node>')
예제 #10
0
def test_node():
    node1 = Node(
        '_',
        'node1.puppet.board',
        report_timestamp='2013-08-01T09:57:00.000Z',
        catalog_timestamp='2013-08-01T09:57:00.000Z',
        facts_timestamp='2013-08-01T09:57:00.000Z',
        status='unreported',
        unreported_time='0d 5h 20m',
    )

    node2 = Node(
        '_',
        'node2.puppet.board',
        deactivated='2013-08-01T09:57:00.000Z',
        report_timestamp=None,
        catalog_timestamp=None,
        facts_timestamp=None,
    )

    assert node1.name == 'node1.puppet.board'
    assert node1.deactivated is False
    assert node1.report_timestamp is not None
    assert node1.facts_timestamp is not None
    assert node1.catalog_timestamp is not None
    assert node1.status is 'unreported'
    assert node1.unreported_time is '0d 5h 20m'
    assert str(node1) == str('node1.puppet.board')
    assert repr(node1) == str('<Node: node1.puppet.board>')

    assert node2.name == 'node2.puppet.board'
    assert node2.deactivated is not False
    assert node2.report_timestamp is None
    assert node2.catalog_timestamp is None
    assert node2.facts_timestamp is None
    assert str(node2) == str('node2.puppet.board')
    assert repr(node2) == str('<Node: node2.puppet.board>')
예제 #11
0
    def test_without_status(self):
        node = Node(
            '_',
            'node',
            report_timestamp='2013-08-01T09:57:00.000Z',
            catalog_timestamp='2013-08-01T09:57:00.000Z',
            facts_timestamp='2013-08-01T09:57:00.000Z',
        )

        assert node.name == 'node'
        assert node.deactivated is False
        assert node.report_timestamp is not None
        assert node.facts_timestamp is not None
        assert node.catalog_timestamp is not None
        assert str(node) == str('node')
        assert unicode(node) == unicode('node')
        assert repr(node) == str('<Node: node>')
예제 #12
0
def mock_puppetdb_default_nodes(mocker):
    timestamp = '2013-08-01T09:57:00.000Z'
    report_hash = '1234567'
    transaction = '7890'
    version = '3.8.5'
    node_list = [
        Node('_',
             'node-%s' % status,
             report_timestamp=timestamp,
             latest_report_hash=report_hash,
             catalog_timestamp=timestamp,
             facts_timestamp=timestamp,
             status_report=status,
             report=Report('_', 'node-%s', report_hash, timestamp, timestamp,
                           timestamp, version, '6', version, transaction))
        for status in ['failed', 'changed', 'unchanged', 'noop', 'unreported']
    ]

    return mocker.patch.object(app.puppetdb,
                               'nodes',
                               return_value=iter(node_list))
예제 #13
0
    def test_without_status(self):
        node = Node(
            '_',
            'node',
            report_timestamp='2013-08-01T09:57:00.000Z',
            catalog_timestamp='2013-08-01T09:57:00.000Z',
            facts_timestamp='2013-08-01T09:57:00.000Z',
        )

        assert node.name == 'node'
        assert node.deactivated is False
        assert node.expired is False
        assert node.report_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.facts_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert node.catalog_timestamp == \
            json_to_datetime('2013-08-01T09:57:00.000Z')
        assert str(node) == str('node')
        assert str(node) == str('node')
        assert repr(node) == str('<Node: node>')
예제 #14
0
    def nodes(self, unreported=2, with_status=False, **kwargs):
        """Query for nodes by either name or query. If both aren't
        provided this will return a list of all nodes. This method
        also fetches the nodes status and event counts of the latest
        report from puppetdb.

        :param with_status: (optional) include the node status in the\
                           returned nodes
        :type with_status: :bool:
        :param unreported: (optional) amount of hours when a node gets
                           marked as unreported
        :type unreported: :obj:`None` or integer
        :param \*\*kwargs: The rest of the keyword arguments are passed
                           to the _query function

        :returns: A generator yieling Nodes.
        :rtype: :class:`pypuppetdb.types.Node`
        """
        nodes = self._query('nodes', **kwargs)
        now = datetime.datetime.utcnow()
        # If we happen to only get one node back it
        # won't be inside a list so iterating over it
        # goes boom. Therefor we wrap a list around it.
        if type(nodes) == dict:
            nodes = [
                nodes,
            ]

        if with_status:
            latest_events = self.event_counts(query=EqualsOperator(
                "latest_report?", True),
                                              summarize_by='certname')

        for node in nodes:
            node['status_report'] = None
            node['events'] = None

            if with_status:
                status = [
                    s for s in latest_events
                    if s['subject']['title'] == node['certname']
                ]

                try:
                    node['status_report'] = node['latest_report_status']

                    if status:
                        node['events'] = status[0]
                except KeyError:
                    if status:
                        node['events'] = status = status[0]
                        if status['successes'] > 0:
                            node['status_report'] = 'changed'
                        if status['noops'] > 0:
                            node['status_report'] = 'noop'
                        if status['failures'] > 0:
                            node['status_report'] = 'failed'
                    else:
                        node['status_report'] = 'unchanged'

                # node report age
                if node['report_timestamp'] is not None:
                    try:
                        last_report = json_to_datetime(
                            node['report_timestamp'])
                        last_report = last_report.replace(tzinfo=None)
                        unreported_border = now - timedelta(hours=unreported)
                        if last_report < unreported_border:
                            delta = (now - last_report)
                            node['unreported'] = True
                            node['unreported_time'] = '{0}d {1}h {2}m'.format(
                                delta.days, int(delta.seconds / 3600),
                                int((delta.seconds % 3600) / 60))
                    except AttributeError:
                        node['unreported'] = True

                if not node['report_timestamp']:
                    node['unreported'] = True

            yield Node(self,
                       name=node['certname'],
                       deactivated=node['deactivated'],
                       expired=node['expired'],
                       report_timestamp=node['report_timestamp'],
                       catalog_timestamp=node['catalog_timestamp'],
                       facts_timestamp=node['facts_timestamp'],
                       status_report=node['status_report'],
                       noop=node.get('latest_report_noop'),
                       noop_pending=node.get('latest_report_noop_pending'),
                       events=node['events'],
                       unreported=node.get('unreported'),
                       unreported_time=node.get('unreported_time'),
                       report_environment=node['report_environment'],
                       catalog_environment=node['catalog_environment'],
                       facts_environment=node['facts_environment'],
                       latest_report_hash=node.get('latest_report_hash'),
                       cached_catalog_status=node.get('cached_catalog_status'))
예제 #15
0
    def nodes(self, name=None, query=None, unreported=2, with_status=False):
        """Query for nodes by either name or query. If both aren't
        provided this will return a list of all nodes. This method
        also fetches the nodes status and event counts of the latest
        report from puppetdb.

        :param name: (optional)
        :type name: :obj:`None` or :obj:`string`
        :param query: (optional)
        :type query: :obj:`None` or :obj:`string`
        :param with_status: (optional) include the node status in the\
                           returned nodes
        :type with_status: :bool:
        :param unreported: (optional) amount of hours when anode gets
                           marked as unreported
        :type unreported: :obj:`None` or integer

        :returns: A generator yieling Nodes.
        :rtype: :class:`pypuppetdb.types.Node`
        """
        nodes = self._query('nodes', path=name, query=query)
        # If we happen to only get one node back it
        # won't be inside a list so iterating over it
        # goes boom. Therefor we wrap a list around it.
        if type(nodes) == dict:
            nodes = [
                nodes,
            ]

        if with_status:
            latest_events = self._query('event-counts',
                                        query='["=","latest-report?",true]',
                                        summarize_by='certname')

        for node in nodes:
            node['unreported_time'] = None
            node['status'] = None

            if with_status:
                status = [
                    s for s in latest_events
                    if s['subject']['title'] == node['name']
                ]

            # node status from events
            if with_status and status:
                node['events'] = status = status[0]
                if status['successes'] > 0:
                    node['status'] = 'changed'
                if status['failures'] > 0:
                    node['status'] = 'failed'
            else:
                node['status'] = 'unchanged'
                node['events'] = None

            # node report age
            if with_status and node['report_timestamp'] is not None:
                try:
                    last_report = json_to_datetime(node['report_timestamp'])
                    last_report = last_report.replace(tzinfo=None)
                    now = datetime.utcnow()
                    unreported_border = now - timedelta(hours=unreported)
                    if last_report < unreported_border:
                        delta = (datetime.utcnow() - last_report)
                        node['status'] = 'unreported'
                        node['unreported_time'] = '{0}d {1}h {2}m'.format(
                            delta.days, int(delta.seconds / 3600),
                            int((delta.seconds % 3600) / 60))
                except AttributeError:
                    node['status'] = 'unreported'

            if not node['report_timestamp']:
                node['status'] = 'unreported'

            yield Node(self,
                       node['name'],
                       deactivated=node['deactivated'],
                       report_timestamp=node['report_timestamp'],
                       catalog_timestamp=node['catalog_timestamp'],
                       facts_timestamp=node['facts_timestamp'],
                       status=node['status'],
                       events=node['events'],
                       unreported_time=node['unreported_time'])
예제 #16
0
 def test_with_latest_report_hash(self):
     node = Node('_', 'node', latest_report_hash='hash#1')
     assert node.name == 'node'
     assert node.latest_report_hash == 'hash#1'
예제 #17
0
파일: pql.py 프로젝트: gdubicki/pypuppetdb
    def pql(self,
            pql,
            with_status=False,
            unreported=2,
            with_event_numbers=True):
        """Makes a PQL (Puppet Query Language) and tries to cast results
        to a rich type. If it won't work, returns plain dicts.

        :param pql: PQL query
        :type pql: :obj:`string`

        :param with_status: (optional, only for queries for nodes) include
                           the node status in the returned nodes
        :type with_status: :bool:
        :param unreported: (optional, only for queries for nodes) amount
                           of hours when a node gets marked as unreported
        :type unreported: :obj:`None` or integer
        :param with_event_numbers: (optional, only for queries for nodes)
                           include the exact number of
                           changed/unchanged/failed/noop events when
                           with_status is set to True. If set to False
                           only "some" string is provided if there are
                           resources with such status in the last report.
                           This provides performance benefits as potentially
                           slow event-counts query is omitted completely.
        :type with_event_numbers: :bool:

        :returns: A generator yielding elements of a rich type or plain dicts
        """

        type_class = self._get_type_from_query(pql)

        if type_class == Node and (with_status or unreported != 2
                                   or not with_event_numbers):
            log.error(
                "with_status, unreported and with_event_numbers are used only"
                " for queries for nodes!")
            raise APIError

        for element in self._pql(pql=pql):
            if type_class == Node:

                # TODO: deduplicate this - see QueryAPI.nodes()

                now = datetime.utcnow()

                latest_events = None
                if with_status and with_event_numbers:
                    latest_events = self._query(
                        'event-counts',
                        query=EqualsOperator("latest_report?", True),
                        summarize_by='certname',
                    )

                yield Node.create_from_dict(self, element, with_status,
                                            with_event_numbers, latest_events,
                                            now, unreported)

            elif type_class == Report:
                yield Report.create_from_dict(self, element)
            elif type_class:
                yield type_class.create_from_dict(element)
            else:
                yield element