Skip to content

daradib/pypuppet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pypuppet

Python wrapper for Puppet REST API

This package wraps the Puppet REST API to make it easier for Python scripts to integrate with Puppet. Persistent cache is used to reduce calls to the API.

Testing, feedback, and pull requests are welcome.

Kudos to my employer, Kloudless, for giving me permission to publish this.

Usage

>>> import puppet
>>> p = puppet.Puppet()

By default, the Puppet instance will use an unauthenticated SSL connection to localhost. A better example would be to use client authentication.

>>> p = puppet.Puppet(host='puppetmaster.example.com',
... port=8140,
... key_file='api-key.pem',
... cert_file='api-cert.pem',
... ssl_verify=True,
... cache_enabled=True,
... cache_file='pypuppet_cache',
... cache_backend='sqlite',
... cache_expire_after=3600)

Replace puppetmaster.example.com with the hostname of the puppet master and api-key.pem/api-cert.pem with the client SSL key/certificate files. SSL verification is enabled by default. Cache is enabled by default with multiple backend options (sqlite (default), memory, mongodb, redis). Default cache file will be stored at pypuppet_cache.sqlite.

Node object

Given a puppet node called puppetnode.example.com,

>>> n = p.node('puppetnode.example.com')
>>> str(n)
'puppetnode.example.com'
>>> dir(n)
['__doc__', '__init__', '__module__', '__str__', 'catalog', 'certificate', 'certificate_status', 'certname', 'classes', 'environment', 'facts', 'node', 'parameters', 'requestor']

An optional node environment argument can be provided. Note that external node classifiers may override the requested environment.

>>> n_prod = p.node('puppetnode.example.com', environment='production')

If a node is not found, puppet.APIError will be raised.

certname

>>> n.certname
'puppetnode.example.com'

classes

>>> type(n.classes)
<type 'dict'>

environment

>>> n.environment
'production'

facts

>>> type(n.facts)
<type 'dict'>
>>> n.facts['osfamily'] + "-" + n.facts['architecture']
'RedHat-x86_64'

node

>>> type(n.node)
<type 'dict'>
>>> sorted(n.node.keys())
['classes', 'environment', 'expiration', 'facts', 'name', 'parameters', 'time']

parameters

>>> type(n.parameters)
<type 'dict'>

certificate

method

>>> type(n.certificate())
<type 'str'>
>>> n.certificate().startswith('-----BEGIN CERTIFICATE')
True

certificate_status

method

>>> n.certificate_status()
'signed'

catalog

method (compiles and downloads catalog)

>>> catalog = n.catalog()
>>> type(catalog)
<type 'dict'>
>>> sorted(catalog.keys())
[u'classes', u'edges', u'environment', u'name', u'resources', u'tags', u'version']

Methods

In addition to the node method which creates a Node instance, there are three other methods in the Puppet instance.

  • certificates: list certnames of known SSL certificates
  • certificate_requests: list certnames of SSL certificate requests
  • facts_search: list nodes matching arguments of fact comparisons

Note that these methods return lists of strings, not lists of Node objects (which would be an expensive API call).

>>> [type(certnames[0]) for certnames in (p.certificates(),
... p.facts_search(('processorcount', 'ge', 1)))]
[<type 'str'>, <type 'str'>]

However, each string can be directly passed as the argument to the node method to create a Node object. A try-except code block is recommended to gracefully handle exceptions caused by non-existent nodes.

>>> for certname in p.certificates():
...     try:
...         n_ = p.node(certname)
...         break
...     except puppet.APIError:
...         # node probably does not exist
...         continue
>>> dir(n_) == dir(n)
True

Each argument (if provided) of facts_search must have two or three elements. The first argument is the name of the fact and the last argument is the string for comparison. If three arguments are provided, the second argument is the comparison type. The arguments are combined with boolean AND. Refer to the Puppet REST API documentation on facts search.

>>> if p.facts_search(('architecture', 'amd64'),('osfamily', 'Debian')):
...     print(True)
True
>>> long_running_servers = p.facts_search(('uptime_days', 'gt', 100))

Requestor object

Direct invocation of the API can be done using the Requestor object's get method, which takes four arguments:

  • resource (required)
  • key (default: 'no_key')
  • environment (default: 'production')
  • parser 'yaml' (default), 'pson', or 's'

For example:

>>> crl = p.requestor.get('certificate_revocation_list', 'ca', parser='s')
>>> type(crl)
<type 'str'>
>>> crl.startswith('-----BEGIN X509 CRL')
True

Some other examples based on the Puppet REST API documentation:

p.requestor.get('resource', 'package/puppet')
p.requestor.get('resources', 'user')

Getting started

Install the module using pip.

$ pip install https://github.com/daradib/pypuppet/archive/master.tar.gz

Alternatively, you can move the puppet directory to your Python PATH or wherever a script that imports it will be located. The only dependency is PyYAML.

The module defaults to using an unauthenticated SSL connection. You may want to create and use a client SSL key/certificate signed by the Puppet CA. On the puppet master (with root privileges):

$ puppet cert generate api

Replace api with another certname if desired.

This will generate $vardir/ssl/private_keys/api.pem and $vardir/ssl/certs/api.pem, which should be moved or otherwise made accessible to the user and host using pypuppet, if necessary. On Debian, $vardir defaults to /var/lib/puppet.

To allow access to the REST API, the puppet master auth.conf file needs to be changed. auth.conf.example is included in this directory as an example.

Caveats

Not currently supported:

  • PUT requests (sending and signing certificate requests, sending facts and reports, putting files in the file bucket)

Author

Dara Adib for Kloudless, Inc.

Contributors

License

Copyright 2012-2013 Kloudless, Inc.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

About

Python wrapper for Puppet REST API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages