From 770cdc202a2451086103e2d6940f06bf54c426eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Sun, 19 Jun 2022 03:05:46 +0200 Subject: work --- .pylintrc | 3 ++ pyenc/__init__.py | 104 ++++++++++++++++-------------------------------------- pyenc/api.py | 78 ++++++++++++++++++++++++++++++++++++++++ pyenc/enc.py | 24 ++++++++----- 4 files changed, 127 insertions(+), 82 deletions(-) create mode 100644 .pylintrc create mode 100644 pyenc/api.py diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..ab6f45d --- /dev/null +++ b/.pylintrc @@ -0,0 +1,3 @@ +[MESSAGES CONTROL] +disable=consider-using-f-string, + missing-module-docstring diff --git a/pyenc/__init__.py b/pyenc/__init__.py index d5ec4f4..cd0d57d 100644 --- a/pyenc/__init__.py +++ b/pyenc/__init__.py @@ -1,5 +1,9 @@ """App object setup for application.""" +import random +import json +import yaml + import flask from flask import ( Flask, @@ -10,12 +14,10 @@ from flask import ( url_for ) -import random -import json - from . import model - -import yaml +from . import db +from . import enc +from . import api def create_app(): @@ -23,16 +25,20 @@ def create_app(): Create new flask app. Should bind everything needed to it. + + This method is also used by `flask run` + https://flask.palletsprojects.com/en/2.1.x/cli/ """ app = Flask(__name__, instance_relative_config=True) app.config.from_pyfile('settings.py') - from . import db - db.init_app(app) - - from . import enc - enc.init_app(app) + for module in [ + db, + enc, + api, + ]: + module.init_app(app) # not API @app.route('/') @@ -52,70 +58,20 @@ def create_app(): flash('Classes removed') return redirect(url_for('root_page')) - # API - @app.route('/api/list-classes') - def list_classes(): - q = request.args.get('q', '') - qq = '%{}%'.format('%'.join(q.split(' '))) - - results = \ - model \ - .PuppetClass \ - .query \ - .where(model.PuppetClass.class_name.like(qq)) \ - .all() - print(qq) - return Response(json.dumps([x.class_name for x in results]), - mimetype='application/json') - - @app.route('/api/classes-for') - def classes_for(): - fqdn = request.args.get('fqdn') - classes = [cls.class_name - for cls in model.Host.query.where(model.Host.fqdn == fqdn) - .first().classes] - return Response(json.dumps(classes), - mimetype='application/json') - - @app.route('/api/change-classes', methods=['POST']) - def change_classes(): - 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'])) - - @app.route('/api/hosts') - def list_hosts(): - data = [x.serialize() for x in model.Host.query.all()] - return Response(flask.json.dumps(data), - mimetype='application/json') - - @app.route('/enc') - def enc(): - fqdn = request.args.get('fqdn', 'default') - host = model.Host.query.where(model.Host.fqdn == fqdn).first() - if not host: - return Response(f"No host with name {fqdn}", - status=404) - out = { - 'environment': host.environment, - 'classes': [cls.class_name for cls in host.classes], - } - return Response(yaml.dump(out), - mimetype='application/x-yaml') + # @app.route('/enc') + # def enc(): + # fqdn = request.args.get('fqdn', 'default') + # host = model.Host.query.where(model.Host.fqdn == fqdn).first() + # if not host: + # return Response(f"No host with name {fqdn}", + # status=404) + + # out = { + # 'environment': host.environment, + # 'classes': [cls.class_name for cls in host.classes], + # } + # return Response(yaml.dump(out), + # mimetype='application/x-yaml') return app diff --git a/pyenc/api.py b/pyenc/api.py new file mode 100644 index 0000000..8fea554 --- /dev/null +++ b/pyenc/api.py @@ -0,0 +1,78 @@ +import json + +import flask +from flask import ( + Blueprint, + Response, + request, + url_for + ) +from . import model +# from . import db + +api = Blueprint('api', __name__) +# API +@api.route('/list-classes') +def list_classes(): + """Return all classes fuzzy matching q.""" + query = request.args.get('q', '') + wildcarded_query = '%{}%'.format('%'.join(query.split(' '))) + + results = \ + model \ + .PuppetClass \ + .query \ + .where(model.PuppetClass.class_name.like(wildcarded_query)) \ + .all() + print(wildcarded_query) + return Response(json.dumps([x.class_name for x in results]), + mimetype='application/json') + +@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 Response(json.dumps(classes), + mimetype='application/json') + +@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'])) + +@api.route('/hosts') +def list_hosts(): + """Return all hosts.""" + data = [x.serialize() for x in model.Host.query.all()] + return Response(json.dumps(data), + mimetype='application/json') + +def init_app(app): + """Register blueprint to app.""" + app.register_blueprint(api) diff --git a/pyenc/enc.py b/pyenc/enc.py index 24f9fdc..e0f3f8d 100644 --- a/pyenc/enc.py +++ b/pyenc/enc.py @@ -1,15 +1,22 @@ +""" +Command line entry point for Puppet External Node Classifier (enc). +""" + import click -from flask import current_app, g -from flask.cli import with_appcontext -from .db import db +import yaml +# from flask import current_app, g +# from flask.cli import with_appcontext, AppGroup +from flask.cli import AppGroup +# from .db import db from . import model -import yaml -@click.command('enc') -@click.option('--fqdn', help='Node to get data for') -@with_appcontext +app_group = AppGroup('user', help="Testt") + +@app_group.command('enc') +@click.argument('fqdn') +# @with_appcontext def run_enc(fqdn): """ Run the puppet node classifier. @@ -25,8 +32,9 @@ def run_enc(fqdn): 'classes': [cls.class_name for cls in host.classes], } print(yaml.dump(out)) + return 0 def init_app(app): """Add puppet enc click to current flask app.""" - app.cli.add_command(run_enc) + app.cli.add_command(app_group) -- cgit v1.2.3