aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2022-06-19 03:05:46 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2022-06-19 03:05:46 +0200
commit770cdc202a2451086103e2d6940f06bf54c426eb (patch)
treef62534509848d6c3146f9882c79eea4b0d5513e9
parentMerge commit_classes into enumerate_classes. (diff)
downloadpuppet-classifier-770cdc202a2451086103e2d6940f06bf54c426eb.tar.gz
puppet-classifier-770cdc202a2451086103e2d6940f06bf54c426eb.tar.xz
work
-rw-r--r--.pylintrc3
-rw-r--r--pyenc/__init__.py104
-rw-r--r--pyenc/api.py78
-rw-r--r--pyenc/enc.py24
4 files changed, 127 insertions, 82 deletions
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)