1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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.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.Environment.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.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.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')
|