Support PuppetDB API v3.

Recently changes were made to pypuppetdb to support, at a basic level,
the v3 API introduced with PuppetDB 1.5.

This commit changes some internals of Puppetboard to handle the new
situation:
 * The experimental endpoints are gone, so is the ExperimentalDisabled
   Error;
 * v2 API can no longer access Reports/Events so we now check that we're
   talking at least v3 API;
 * Introduce a configuration setting PUPPETDB_API which takes an integer
   repersenting the API version we want to talk.
This commit is contained in:
Daniele Sluijters
2013-10-11 11:17:53 +02:00
parent 3b4db8f37e
commit cc87e54cea
5 changed files with 17 additions and 20 deletions

View File

@@ -12,7 +12,6 @@ from flask import (
)
from pypuppetdb import connect
from pypuppetdb.errors import ExperimentalDisabledError
from puppetboard.forms import QueryForm
from puppetboard.utils import (
@@ -27,13 +26,13 @@ app.config.from_envvar('PUPPETBOARD_SETTINGS', silent=True)
app.secret_key = os.urandom(24)
puppetdb = connect(
api_version=app.config['PUPPETDB_API'],
host=app.config['PUPPETDB_HOST'],
port=app.config['PUPPETDB_PORT'],
ssl=app.config['PUPPETDB_SSL'],
ssl_key=app.config['PUPPETDB_KEY'],
ssl_cert=app.config['PUPPETDB_CERT'],
timeout=app.config['PUPPETDB_TIMEOUT'],
experimental=app.config['PUPPETDB_EXPERIMENTAL'])
timeout=app.config['PUPPETDB_TIMEOUT'],)
numeric_level = getattr(logging, app.config['LOGLEVEL'].upper(), None)
if not isinstance(numeric_level, int):
@@ -58,7 +57,8 @@ def not_found(e):
@app.errorhandler(412)
def precond_failed(e):
"""We're slightly abusing 412 to handle ExperimentalDisabled errors."""
"""We're slightly abusing 412 to handle missing features
depending on the API version."""
return render_template('412.html'), 412
@app.errorhandler(500)
@@ -112,7 +112,7 @@ def node(node_name):
"""
node = get_or_abort(puppetdb.node, node_name)
facts = node.facts()
if app.config['PUPPETDB_EXPERIMENTAL']:
if app.config['PUPPETDB_API'] > 2:
reports = ten_reports(node.reports())
else:
reports = iter([])
@@ -123,21 +123,21 @@ def node(node_name):
def reports():
"""Doesn't do much yet but is meant to show something like the reports of
the last half our, something like that."""
if app.config['PUPPETDB_EXPERIMENTAL']:
if app.config['PUPPETDB_API'] > 2:
return render_template('reports.html')
else:
log.warn('Access to experimental endpoint not allowed.')
log.warn('PuppetDB API prior to v3 cannot access reports.')
abort(412)
@app.route('/reports/<node>')
def reports_node(node):
"""Fetches all reports for a node and processes them eventually rendering
a table displaying those reports."""
if app.config['PUPPETDB_EXPERIMENTAL']:
if app.config['PUPPETDB_API'] > 2:
reports = ten_reports(yield_or_stop(
puppetdb.reports('["=", "certname", "{0}"]'.format(node))))
else:
log.warn('Access to experimental endpoint not allowed.')
log.warn('PuppetDB API prior to v3 cannot access reports.')
abort(412)
return render_template('reports_node.html', reports=reports,
nodename=node)
@@ -146,10 +146,10 @@ def reports_node(node):
def report(node, report_id):
"""Displays a single report including all the events associated with that
report and their status."""
if app.config['PUPPETDB_EXPERIMENTAL']:
if app.config['PUPPETDB_API'] > 2:
reports = puppetdb.reports('["=", "certname", "{0}"]'.format(node))
else:
log.warn('Access to experimental endpoint not allowed.')
log.warn('PuppetDB API prior to v3 cannot access reports.')
abort(412)
for report in reports:

View File

@@ -4,7 +4,7 @@ PUPPETDB_SSL=False
PUPPETDB_KEY=None
PUPPETDB_CERT=None
PUPPETDB_TIMEOUT=20
PUPPETDB_EXPERIMENTAL=False
PUPPETDB_API=3
DEV_LISTEN_HOST='127.0.0.1'
DEV_LISTEN_PORT=5000
LOGLEVEL='info'

View File

@@ -3,8 +3,8 @@
<div class="container" style="margin-bottom:55px;">
<div class="row">
<div class="span12">
<h2>Experimental Disabled</h2>
<p>You're trying to access a feature restricted to PuppetDB's Experimental API but haven't configured Puppetboard to allow this.</p>
<h2>Feature unavailable</h2>
<p>You've configured Puppetboard with an API version that does not support this feature.</p>
</div>
</div>
</div>

View File

@@ -27,7 +27,7 @@
</tbody>
</table>
</div>
{% if config.PUPPETDB_EXPERIMENTAL %}
{% if config.PUPPETDB_API > 2 %}
<div class="span4">
<h1>Facts</h1>
{{macros.facts_table(facts, condensed=True, margin_top=10)}}

View File

@@ -2,7 +2,7 @@ from __future__ import absolute_import
from __future__ import unicode_literals
from requests.exceptions import HTTPError, ConnectionError
from pypuppetdb.errors import EmptyResponseError, ExperimentalDisabledError
from pypuppetdb.errors import EmptyResponseError
from flask import abort
@@ -18,8 +18,6 @@ def get_or_abort(func, *args, **kwargs):
abort(e.response.status_code)
except ConnectionError:
abort(500)
except ExperimentalDisabledError:
abort(412)
except EmptyResponseError:
abort(204)
@@ -47,6 +45,5 @@ def yield_or_stop(generator):
yield next(generator)
except StopIteration:
raise
except (ExperimentalDisabledError, EmptyResponseError,
ConnectionError, HTTPError):
except (EmptyResponseError, ConnectionError, HTTPError):
raise StopIteration