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')