summaryrefslogtreecommitdiffstats
path: root/common/recipes-rest/rest-api/files/rest.py
blob: 0a90d54ccdd6ce77ff37a9cfe6edd2359c1a81e9 (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
#!/usr/bin/env python
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

from ctypes import *
from bottle import route, run, template, request, response, ServerAdapter
from bottle import abort
from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
import json
import ssl
import socket
import os
from tree import tree
from node import node
from plat_tree import init_plat_tree

CONSTANTS = {
    'certificate': '/usr/lib/ssl/certs/rest_server.pem',
}

root = init_plat_tree()

# Generic router for incoming requests
@route('/<path:path>', method='ANY')
def url_router(path):
    token = path.split('/')
    # Find the Node
    r = root
    for t in token:
        r = r.getChildByName(t)
        if r == None:
            return r
    c = r.data

    # Handle GET request
    if request.method == 'GET':
        # Gather info/actions directly from respective node
        info = c.getInformation()
        actions = c.getActions()

        # Create list of resources from tree structure
        resources = []
        ca = r.getChildren()
        for t in ca:
            resources.append(t.name)
        result = {'Information': info,
                  'Actions': actions,
                  'Resources': resources }

        return result

    # Handle POST request
    if request.method == 'POST':
        return c.doAction(json.load(request.body))

    return None

run(host = "::", port = 8080)

# TODO: Test the https connection with proper certificates
# SSL Wrapper for Rest API
class SSLWSGIRefServer(ServerAdapter):
    def run(self, handler):
        if self.quiet:
            class QuietHandler(WSGIRequestHandler):
                def log_request(*args, **kw): pass
            self.options['handler_class'] = QuietHandler

        # IPv6 Support
        server_cls = self.options.get('server_class', WSGIServer)

        if ':' in self.host:
            if getattr(server_cls, 'address_family') == socket.AF_INET:
                class server_cls(server_cls):
                    address_family = socket.AF_INET6

        srv = make_server(self.host, self.port, handler,
                server_class=server_cls, **self.options)
        srv.socket = ssl.wrap_socket (
                srv.socket,
                certfile=CONSTANTS['certificate'],
                server_side=True)
        srv.serve_forever()

# Use SSL if the certificate exists. Otherwise, run without SSL.
if os.access(CONSTANTS['certificate'], os.R_OK):
    run(server=SSLWSGIRefServer(host="::", port=8443))
else:
    run(host = "::", port = 8080)
OpenPOWER on IntegriCloud