Page MenuHomePhabricator
Paste P7931

Flask/PuppetDB PoC
ActivePublic

Authored by faidon on Dec 19 2018, 6:22 PM.
Tags
Referenced Files
F27645339: Flask/PuppetDB PoC
Dec 19 2018, 6:24 PM
F27645326: Flask/PuppetDB PoC
Dec 19 2018, 6:24 PM
F27645245: Flask/PuppetDB PoC
Dec 19 2018, 6:22 PM
#!/usr/bin/env python3
from flask import Flask, abort, jsonify
import pypuppetdb
import pypuppetdb.QueryBuilder as pqb
app = Flask(__name__)
# facts that are non-sensitive and safe to process
WHITELIST = [
"serial_number",
]
@app.route('/v1/fact/<fact_name>')
def fact(fact_name):
if fact_name not in WHITELIST:
abort(403)
db = pypuppetdb.connect()
fact_list = db.facts(query=pqb.EqualsOperator("name", fact_name))
result = {f.node: f.value for f in fact_list}
return jsonify(result)

Event Timeline

faidon edited the content of this paste. (Show Details)
#!/usr/bin/env python3
"""Proxy access to PuppetDB facts.

Provides an extremely thin filtering proxy API for querying fact lists
from PuppetDB for external validation.
"""

from flask import Flask, abort, jsonify
import requests

# Allowed Facts
WHITELIST = ["serialnumber"]

# PuppetDB api URL template
PUPPETDB_URL = "http://localhost:8080/pdb/query/v4/facts/{fact}"

app = Flask(__name__)


@app.route("/v1/factcheck/<fact_name>")
def factcheck(fact_name):
    """Primary api endpoint.

    Accepts a single fact name and returns a list of [hostname, value].
    """

    if not fact_name in WHITELIST:
        abort(403)

    results = requests.get(PUPPETDB_URL.format(fact=fact_name))
    if r.status_code != 200:
        abort(r.status_code)

    fact_list = []
    for fact in results.json():
        value = fact["value"]
        if value == "Not Specified":
            value = None
        fact_list.append((fact["certname"], value))

    return jsonify(fact_list)

Here is a version that removes the req on pypuppetdb.