Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding API Endpoints and Additional Functionality for PuppetDB 4.2.0 #106

Merged
merged 3 commits into from
Jan 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion pypuppetdb/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
)
from pypuppetdb.types import (
Node, Fact, Resource,
Report, Event, Catalog
Report, Event, Catalog,
Inventory
)
from pypuppetdb.QueryBuilder import *

Expand Down Expand Up @@ -44,6 +45,7 @@
'fact-contents': 'pdb/query/v4/fact-contents',
'edges': 'pdb/query/v4/edges',
'pql': 'pdb/query/v4',
'inventory': 'pdb/query/v4/inventory',
}

PARAMETERS = {
Expand Down Expand Up @@ -815,3 +817,24 @@ def reports(self, **kwargs):
catalog_uuid=report.get('catalog_uuid'),
cached_catalog_status=report.get('cached_catalog_status')
)

def inventory(self, **kwargs):
"""Get Node and Fact information with an alternative query syntax
for structured facts instead of using the facts, fact-contents and
factsets endpoints for many fact-related queries.

:param \*\*kwargs: The rest of the keyword arguments are passed
to the _query function.

:returns: A generator yielding Inventory
:rtype: :class:`pypuppetdb.types.Inventory`
"""
inventory = self._query('inventory', **kwargs)
for inv in inventory:
yield Inventory(
node=inv.certname,
time=inv.timestamp,
environment=inv.environment,
facts=inv.facts,
trusted=inv.trusted
)
63 changes: 61 additions & 2 deletions pypuppetdb/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ class Report(object):
error. Can be one of 'explicitly_requested', 'on_failure',\
'not_used' not 'null'.
:type cached_catalog_status: :obj:`string`
:param producer: (Optional) The certname of the Puppet Master that\
sent the report to PuppetDB
:type producer: :obj:`string`

:ivar node: The hostname this report originated from.
:ivar hash\_: Unique identifier of this report.
Expand All @@ -164,12 +167,15 @@ class Report(object):
:ivar cached_catalog_status: :obj:`string` identifying if this Puppet run\
used a cached catalog, if so weather it was a result of an error or\
otherwise.
:ivar producer: :obj:`string` representing the certname of the Puppet\
Master that sent the report to PuppetDB
"""
def __init__(self, api, node, hash_, start, end, received, version,
format_, agent_version, transaction, status=None,
metrics={}, logs={}, environment=None,
noop=False, noop_pending=False, code_id=None,
catalog_uuid=None, cached_catalog_status=None):
catalog_uuid=None, cached_catalog_status=None,
producer=None):

self.node = node
self.hash_ = hash_
Expand All @@ -188,6 +194,7 @@ def __init__(self, api, node, hash_, start, end, received, version,
self.code_id = code_id
self.catalog_uuid = catalog_uuid
self.cached_catalog_status = cached_catalog_status
self.producer = producer
self.__string = '{0}'.format(self.hash_)

self.__api = api
Expand Down Expand Up @@ -517,6 +524,9 @@ class Catalog(object):
:type code_id: :obj:`string`
:param catalog_uuid: Universally unique identifier of this catalog.
:type catalog_uuid: :obj:`string`
:param producer: The certname of the Puppet Master that sent the catalog\
to PuppetDB
:type producer: :obj:`string`

:ivar node: :obj:`string` Name of the host
:ivar version: :obj:`string` Catalog version from Puppet
Expand All @@ -532,16 +542,20 @@ class Catalog(object):
:ivar code_id: :obj:`string` ties the catalog to the Puppet code that\
generated the catalog
:ivar catalog_uuid: :obj:`string` uniquely identifying this catalog.
:ivar producer: :obj:`string` of the Puppet Master that sent the catalog\
to PuppetDB
"""
def __init__(self, node, edges, resources, version, transaction_uuid,
environment=None, code_id=None, catalog_uuid=None):
environment=None, code_id=None, catalog_uuid=None,
producer=None):

self.node = node
self.version = version
self.transaction_uuid = transaction_uuid
self.environment = environment
self.code_id = code_id
self.catalog_uuid = catalog_uuid
self.producer = producer

self.resources = dict()
for resource in resources:
Expand Down Expand Up @@ -635,3 +649,48 @@ def __str__(self):

def __unicode__(self):
return self.__string


class Inventory(object):
"""This object represents a Node Inventory entry returned from
the Inventory endpoint.

:param node: The certname of the node associated with the inventory.
:type node: :obj:`string`
:param time: The time at which PuppetDB received the facts in the
inventory.
:type time: :obj:`string` formatted as ``%Y-%m-%dT%H:%M:%S.%fZ``
:param environment: The environment associated with the inventory's
certname.
:type environment: :obj:`string`
:param facts: The dictionary of key-value pairs for the nodes
assosciated facts.
:type facts: :obj:`dict`
:param trusted: The trusted data from the node.
:type trusted: :obj:`dict`

:ivar node: The certname of the node associated with the inventory.
:ivar time: The time at which PuppetDB received the facts in the
inventory.
:ivar environment: The environment associated with the inventory's
certname.
:ivar facts: The dictionary of key-value pairs for the nodes
assosciated facts.
:ivar trusted: The trusted data from the node.
"""
def __init__(self, node, time, environment, facts, trusted):
self.node = node
self.time = json_to_datetime(time)
self.environment = environment
self.facts = facts
self.trusted = trusted
self.__string = self.node

def __repr__(self):
return str('<Inventory: {0}>').format(self.__string)

def __str__(self):
return str("{0}").format(self.__string)

def __unicode(self):
return self.__string
79 changes: 78 additions & 1 deletion tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from pypuppetdb.utils import json_to_datetime
from pypuppetdb.types import (
Node, Fact, Resource,
Report, Event, Catalog, Edge
Report, Event, Catalog, Edge,
Inventory
)

if sys.version_info >= (3, 0):
Expand Down Expand Up @@ -438,6 +439,29 @@ def test_report_with_cataloguuid_codeid(self):
assert unicode(report) == unicode('hash#')
assert repr(report) == str('Report: hash#')

def test_report_with_producer(self):
report = Report('_', "test.test.com", "hash#",
'2015-08-31T21:07:00.000Z',
'2015-08-31T21:09:00.000Z',
'2015-08-31T21:10:00.000Z',
'1482347613', 4, '4.2.1',
'af9f16e3-75f6-4f90-acc6-f83d6524a6f3',
producer="puppet01.test.com")

assert report.node == "test.test.com"
assert report.hash_ == 'hash#'
assert report.start == json_to_datetime('2015-08-31T21:07:00.000Z')
assert report.end == json_to_datetime('2015-08-31T21:09:00.000Z')
assert report.received == json_to_datetime('2015-08-31T21:10:00.000Z')
assert report.version == '1482347613'
assert report.format_ == 4
assert report.agent_version == '4.2.1'
assert report.run_time == report.end - report.start
assert report.producer == "puppet01.test.com"
assert str(report) == str('hash#')
assert unicode(report) == unicode('hash#')
assert repr(report) == str('Report: hash#')


class TestEvent(object):
"""Test the Event object."""
Expand Down Expand Up @@ -520,6 +544,20 @@ def test_catalog_uuid(self):
'<Catalog: node/None>')
assert catalog.catalog_uuid == 'univerallyuniqueidentifier'

def test_catalog_producer(self):
catalog = Catalog('node', [], [], 'unique', None,
producer="puppet01.test.com")
assert catalog.node == 'node'
assert catalog.version == 'unique'
assert catalog.transaction_uuid is None
assert catalog.resources == {}
assert catalog.edges == []
assert catalog.producer == 'puppet01.test.com'
assert str(catalog) == str('node/None')
assert unicode(catalog) == unicode('node/None')
assert repr(catalog) == str(
'<Catalog: node/None>')


class TestEdge(object):
"""Test the Edge object."""
Expand All @@ -545,3 +583,42 @@ def test_edge(self):
'file[/etc/ssh/sshd_config] - notify - service[sshd]')
assert repr(edge) == str(
'<Edge: file[/etc/ssh/sshd_config] - notify - service[sshd]>')


class TestInventory(object):
def test_inventory(self):
inv = Inventory(node="test1.test.com",
environment="production",
time='2016-08-18T21:00:00.000Z',
facts={
"hostname": "test1.test.com",
"domain": "test.com",
"puppetversion": "4.6.0"
},
trusted={
"authenticated": "remote",
"domain": "test.com",
"certname": "test1.test.com",
"extensions": {},
"hostname": "test1"
})

assert inv.node == "test1.test.com"
assert inv.environment == "production"
assert inv.time == json_to_datetime('2016-08-18T21:00:00.000Z')
assert inv.facts == {
"hostname": "test1.test.com",
"domain": "test.com",
"puppetversion": "4.6.0"
}
assert inv.trusted == {
"authenticated": "remote",
"domain": "test.com",
"certname": "test1.test.com",
"extensions": {},
"hostname": "test1"
}

assert str(inv) == str("test1.test.com")
assert unicode(inv) == unicode("test1.test.com")
assert repr(inv) == str("<Inventory: test1.test.com>")