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:
@@ -12,7 +12,6 @@ from flask import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from pypuppetdb import connect
|
from pypuppetdb import connect
|
||||||
from pypuppetdb.errors import ExperimentalDisabledError
|
|
||||||
|
|
||||||
from puppetboard.forms import QueryForm
|
from puppetboard.forms import QueryForm
|
||||||
from puppetboard.utils import (
|
from puppetboard.utils import (
|
||||||
@@ -27,13 +26,13 @@ app.config.from_envvar('PUPPETBOARD_SETTINGS', silent=True)
|
|||||||
app.secret_key = os.urandom(24)
|
app.secret_key = os.urandom(24)
|
||||||
|
|
||||||
puppetdb = connect(
|
puppetdb = connect(
|
||||||
|
api_version=app.config['PUPPETDB_API'],
|
||||||
host=app.config['PUPPETDB_HOST'],
|
host=app.config['PUPPETDB_HOST'],
|
||||||
port=app.config['PUPPETDB_PORT'],
|
port=app.config['PUPPETDB_PORT'],
|
||||||
ssl=app.config['PUPPETDB_SSL'],
|
ssl=app.config['PUPPETDB_SSL'],
|
||||||
ssl_key=app.config['PUPPETDB_KEY'],
|
ssl_key=app.config['PUPPETDB_KEY'],
|
||||||
ssl_cert=app.config['PUPPETDB_CERT'],
|
ssl_cert=app.config['PUPPETDB_CERT'],
|
||||||
timeout=app.config['PUPPETDB_TIMEOUT'],
|
timeout=app.config['PUPPETDB_TIMEOUT'],)
|
||||||
experimental=app.config['PUPPETDB_EXPERIMENTAL'])
|
|
||||||
|
|
||||||
numeric_level = getattr(logging, app.config['LOGLEVEL'].upper(), None)
|
numeric_level = getattr(logging, app.config['LOGLEVEL'].upper(), None)
|
||||||
if not isinstance(numeric_level, int):
|
if not isinstance(numeric_level, int):
|
||||||
@@ -58,7 +57,8 @@ def not_found(e):
|
|||||||
|
|
||||||
@app.errorhandler(412)
|
@app.errorhandler(412)
|
||||||
def precond_failed(e):
|
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
|
return render_template('412.html'), 412
|
||||||
|
|
||||||
@app.errorhandler(500)
|
@app.errorhandler(500)
|
||||||
@@ -112,7 +112,7 @@ def node(node_name):
|
|||||||
"""
|
"""
|
||||||
node = get_or_abort(puppetdb.node, node_name)
|
node = get_or_abort(puppetdb.node, node_name)
|
||||||
facts = node.facts()
|
facts = node.facts()
|
||||||
if app.config['PUPPETDB_EXPERIMENTAL']:
|
if app.config['PUPPETDB_API'] > 2:
|
||||||
reports = ten_reports(node.reports())
|
reports = ten_reports(node.reports())
|
||||||
else:
|
else:
|
||||||
reports = iter([])
|
reports = iter([])
|
||||||
@@ -123,21 +123,21 @@ def node(node_name):
|
|||||||
def reports():
|
def reports():
|
||||||
"""Doesn't do much yet but is meant to show something like the reports of
|
"""Doesn't do much yet but is meant to show something like the reports of
|
||||||
the last half our, something like that."""
|
the last half our, something like that."""
|
||||||
if app.config['PUPPETDB_EXPERIMENTAL']:
|
if app.config['PUPPETDB_API'] > 2:
|
||||||
return render_template('reports.html')
|
return render_template('reports.html')
|
||||||
else:
|
else:
|
||||||
log.warn('Access to experimental endpoint not allowed.')
|
log.warn('PuppetDB API prior to v3 cannot access reports.')
|
||||||
abort(412)
|
abort(412)
|
||||||
|
|
||||||
@app.route('/reports/<node>')
|
@app.route('/reports/<node>')
|
||||||
def reports_node(node):
|
def reports_node(node):
|
||||||
"""Fetches all reports for a node and processes them eventually rendering
|
"""Fetches all reports for a node and processes them eventually rendering
|
||||||
a table displaying those reports."""
|
a table displaying those reports."""
|
||||||
if app.config['PUPPETDB_EXPERIMENTAL']:
|
if app.config['PUPPETDB_API'] > 2:
|
||||||
reports = ten_reports(yield_or_stop(
|
reports = ten_reports(yield_or_stop(
|
||||||
puppetdb.reports('["=", "certname", "{0}"]'.format(node))))
|
puppetdb.reports('["=", "certname", "{0}"]'.format(node))))
|
||||||
else:
|
else:
|
||||||
log.warn('Access to experimental endpoint not allowed.')
|
log.warn('PuppetDB API prior to v3 cannot access reports.')
|
||||||
abort(412)
|
abort(412)
|
||||||
return render_template('reports_node.html', reports=reports,
|
return render_template('reports_node.html', reports=reports,
|
||||||
nodename=node)
|
nodename=node)
|
||||||
@@ -146,10 +146,10 @@ def reports_node(node):
|
|||||||
def report(node, report_id):
|
def report(node, report_id):
|
||||||
"""Displays a single report including all the events associated with that
|
"""Displays a single report including all the events associated with that
|
||||||
report and their status."""
|
report and their status."""
|
||||||
if app.config['PUPPETDB_EXPERIMENTAL']:
|
if app.config['PUPPETDB_API'] > 2:
|
||||||
reports = puppetdb.reports('["=", "certname", "{0}"]'.format(node))
|
reports = puppetdb.reports('["=", "certname", "{0}"]'.format(node))
|
||||||
else:
|
else:
|
||||||
log.warn('Access to experimental endpoint not allowed.')
|
log.warn('PuppetDB API prior to v3 cannot access reports.')
|
||||||
abort(412)
|
abort(412)
|
||||||
|
|
||||||
for report in reports:
|
for report in reports:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ PUPPETDB_SSL=False
|
|||||||
PUPPETDB_KEY=None
|
PUPPETDB_KEY=None
|
||||||
PUPPETDB_CERT=None
|
PUPPETDB_CERT=None
|
||||||
PUPPETDB_TIMEOUT=20
|
PUPPETDB_TIMEOUT=20
|
||||||
PUPPETDB_EXPERIMENTAL=False
|
PUPPETDB_API=3
|
||||||
DEV_LISTEN_HOST='127.0.0.1'
|
DEV_LISTEN_HOST='127.0.0.1'
|
||||||
DEV_LISTEN_PORT=5000
|
DEV_LISTEN_PORT=5000
|
||||||
LOGLEVEL='info'
|
LOGLEVEL='info'
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<div class="container" style="margin-bottom:55px;">
|
<div class="container" style="margin-bottom:55px;">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<h2>Experimental Disabled</h2>
|
<h2>Feature unavailable</h2>
|
||||||
<p>You're trying to access a feature restricted to PuppetDB's Experimental API but haven't configured Puppetboard to allow this.</p>
|
<p>You've configured Puppetboard with an API version that does not support this feature.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{% if config.PUPPETDB_EXPERIMENTAL %}
|
{% if config.PUPPETDB_API > 2 %}
|
||||||
<div class="span4">
|
<div class="span4">
|
||||||
<h1>Facts</h1>
|
<h1>Facts</h1>
|
||||||
{{macros.facts_table(facts, condensed=True, margin_top=10)}}
|
{{macros.facts_table(facts, condensed=True, margin_top=10)}}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from requests.exceptions import HTTPError, ConnectionError
|
from requests.exceptions import HTTPError, ConnectionError
|
||||||
from pypuppetdb.errors import EmptyResponseError, ExperimentalDisabledError
|
from pypuppetdb.errors import EmptyResponseError
|
||||||
|
|
||||||
from flask import abort
|
from flask import abort
|
||||||
|
|
||||||
@@ -18,8 +18,6 @@ def get_or_abort(func, *args, **kwargs):
|
|||||||
abort(e.response.status_code)
|
abort(e.response.status_code)
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
abort(500)
|
abort(500)
|
||||||
except ExperimentalDisabledError:
|
|
||||||
abort(412)
|
|
||||||
except EmptyResponseError:
|
except EmptyResponseError:
|
||||||
abort(204)
|
abort(204)
|
||||||
|
|
||||||
@@ -47,6 +45,5 @@ def yield_or_stop(generator):
|
|||||||
yield next(generator)
|
yield next(generator)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise
|
raise
|
||||||
except (ExperimentalDisabledError, EmptyResponseError,
|
except (EmptyResponseError, ConnectionError, HTTPError):
|
||||||
ConnectionError, HTTPError):
|
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|||||||
Reference in New Issue
Block a user