Paste P7931

Flask/PuppetDB PoC
ActivePublic

Authored by faidon on Wed, Dec 19, 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)
faidon created this paste.Wed, Dec 19, 6:22 PM
faidon edited the content of this paste. (Show Details)Wed, Dec 19, 6:24 PM
faidon edited the content of this paste. (Show Details)

Well that's straight forward!

#!/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.