aboutsummaryrefslogtreecommitdiff
path: root/pyenc/app/api.py
blob: cb80da8e90e573a61f4683e07a4c10a58a364ddd (plain)
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')