diff options
Diffstat (limited to 'pyenc/app/api.py')
-rw-r--r-- | pyenc/app/api.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/pyenc/app/api.py b/pyenc/app/api.py new file mode 100644 index 0000000..a8a37d9 --- /dev/null +++ b/pyenc/app/api.py @@ -0,0 +1,117 @@ +import flask +from flask import ( + Blueprint, + request, + url_for +) + +from . import model + + +def concatenate(listlist): + result = [] + for lst in listlist: + result.extend(lst) + return result + + +api = Blueprint('api', __name__) + + +@api.route('/classes') +def list_classes(): + """Return all classes fuzzy matching q.""" + environment = request.args.get('environment', 'production') + query = request.args.get('q', '') + wildcarded_query = '%{}%'.format('%'.join(query.split(' '))) + + result = model.db.engine.execute(model.db.text(""" + SELECT pc.class_name + FROM environment_classes ec + LEFT JOIN puppet_environment e ON ec.environment_id = e.id + LEFT JOIN puppet_class pc ON ec.class_id = pc.id + WHERE e.name = :environment + AND pc.class_name LIKE :wildcard + """), { + 'environment': environment, + 'wildcard': wildcarded_query, + }) + + return flask.json.jsonify([x for (x,) in result]) + + # results = \ + # model \ + # .PuppetClass \ + # .query \ + # .where(model.PuppetClass.class_name.like(wildcarded_query)) \ + # .where(model.PuppetClass.environments.name == environment) \ + # .all() + # print(wildcarded_query) + # return flask.json.jsonify([x.class_name for x in results]) + + +@api.route('/environments') +def list_environments(): + envs = model.PuppetEnvironment.query.all() + return flask.json.jsonify([env.name for env in envs]) + + +@api.route('/class-file') +def class_file(): + class_name = request.args.get('class') + result = model.PuppetClass.query \ + .where(model.PuppetClass.class_name == class_name) \ + .all() + return flask.json.jsonify(concatenate([ + [f.path for f in x.files] + for x in result])) + + +@api.route('/hosts') +def hosts(): + result = model.Host.query.all() + return flask.json.jsonify([x.fqdn for x in result]) + + +@api.route('/classes-for') +def classes_for(): + """Return classes mapped to host `fqdn'.""" + fqdn = request.args.get('fqdn') + classes = [cls.class_name + for cls in model.Host.query.where(model.Host.fqdn == fqdn) + .first().classes] + return flask.json.jsonify(classes) + + +@api.route('/change-classes', methods=['POST']) +def change_classes(): + """ + Update set of active classes for node. + + Takes a json object as the POST body, which should have the keys + - fqdn :: which host to operate on + - removed :: classes which should be removed + - added :: classes which should be added + """ + j = request.json + host = model.Host.query.where(model.Host.fqdn == j['fqdn']).first() + remove_set = set(j['removed']) + + new_cls = [] + for cls in host.classes: + if cls.class_name in remove_set: + continue + new_cls.append(cls) + host.classes = new_cls + + cls = model.PuppetClass.query \ + .where(model.PuppetClass.class_name.in_(j['added'])) \ + .all() + host.classes.extend(cls) + # print(remove_set, db.db.session.dirty) + return flask.redirect(url_for('classes_for', fqdn=j['fqdn'])) + + +def init_app(app): + """Register blueprint to app.""" + app.register_blueprint(api, url_prefix='/api') |