Add forwarder function to pecan framework
[multicloud/framework.git] / multivimbroker / multivimbroker / api_v2 / api_router / v0_controller.py
1 #    Licensed under the Apache License, Version 2.0 (the "License");
2 #    you may not use this file except in compliance with the License.
3 #    You may obtain a copy of the License at
4 #
5 #        http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #    Unless required by applicable law or agreed to in writing, software
8 #    distributed under the License is distributed on an "AS IS" BASIS,
9 #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 #    See the License for the specific language governing permissions and
11 #    limitations under the License.
12
13 import logging
14 import pecan
15
16 from multivimbroker.swagger import utils
17 from multivimbroker.pub import exceptions
18 from multivimbroker.pub.utils import restcall
19 from multivimbroker.pub.utils import syscomm
20
21
22 logger = logging.getLogger(__name__)
23
24 # TODO: Move to a constant file.
25 REGISTRY_URI = "registry"
26 UNREGISTRY_URI = ""
27 IDENTITY_URI = "identity/v3"
28 IDENTITY_AUTH_URI = "identity/v3/auth/tokens"
29
30
31 class V0_Controller(object):
32
33     @pecan.expose('json', route="swagger.json")
34     def swagger_json(self):
35         return utils.get_swagger_json_data()
36
37     def _filter_illegal_uri(self, uri, method):
38         """
39         Filter unsupported actions, so they can be stopped at begginning.
40         """
41
42         if uri == REGISTRY_URI and method != "POST":
43             pecan.abort(405)
44
45         if uri == UNREGISTRY_URI and method != "DELETE":
46             pecan.abort(405)
47
48         if (uri in (IDENTITY_URI, IDENTITY_AUTH_URI) and
49                 method not in ("POST", "GET")):
50             pecan.abort(405)
51
52     @pecan.expose()
53     def _route(self, remainder, request):
54         uri = "/".join(remainder[1:])
55         method = request.method
56         self._filter_illegal_uri(uri, method)
57
58         return self.forwarder, remainder
59
60     @pecan.expose('json')
61     def forwarder(self, *remainder, **kwargs):
62         """ Forward any requests that don't have a specific match """
63
64         # TODO(xiaohhui): Add validator for vim_id.
65         vim_id = remainder[0]
66         request = pecan.request
67         try:
68             vim_url = syscomm.getMultivimDriver(vim_id,
69                                                 full_path=request.path)
70
71             # NOTE: Not sure headers should be set here. According to original
72             # code, headers are discarded.
73             retcode, content, status_code, resp = restcall.req_by_msb(
74                 vim_url, request.method, content=request.body)
75         except exceptions.NotFound as e:
76             pecan.abort(404, detail=str(e))
77         except Exception as e:
78             pecan.abort(500, detail=str(e))
79
80         if retcode:
81             # Execptions are handled within req_by_msb
82             logger.error("Status code is %s, detail is %s.",
83                          status_code, content)
84         response = pecan.Response(body=content, status=status_code)
85
86         for k in syscomm.getHeadersKeys(resp):
87             response.headers[k] = resp[k]
88
89         return response