blob: 34a83f5223fc608d86d235fec4ba308082593386 [file] [log] [blame]
Matteo Scandolo920e8fd2017-08-08 13:05:24 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Zack Williams6bb2cfe2019-03-27 15:01:45 -070015from __future__ import absolute_import, print_function
Matteo Scandolo920e8fd2017-08-08 13:05:24 -070016
Matteo Scandolo09d469c2017-07-07 11:46:48 -070017import json
Zack Williams6bb2cfe2019-03-27 15:01:45 -070018import os
Matteo Scandolo9ce18252017-06-22 10:48:25 -070019
Zack Williams6bb2cfe2019-03-27 15:01:45 -070020from grpc_client import GRPC_Client
21from klein import Klein
22from multistructlog import create_logger
23from tosca.default import TOSCA_DEFS_DIR
24from tosca.parser import TOSCA_Parser
25from xosconfig import Config
26
27log = create_logger(Config().get("logging"))
28
29
30BANNER = r"""
31 _ ______ _____ __________ _____ _________
Matteo Scandolo9ce18252017-06-22 10:48:25 -070032 | |/ / __ \/ ___/ /_ __/ __ \/ ___// ____/ |
33 | / / / /\__ \ / / / / / /\__ \/ / / /| |
34 / / /_/ /___/ / / / / /_/ /___/ / /___/ ___ |
35/_/|_\____//____/ /_/ \____//____/\____/_/ |_|
36"""
37
Zack Williams6bb2cfe2019-03-27 15:01:45 -070038
Matteo Scandolo9ce18252017-06-22 10:48:25 -070039class TOSCA_WebServer:
Matteo Scandolo9ce18252017-06-22 10:48:25 -070040
Matteo Scandolo09d469c2017-07-07 11:46:48 -070041 current_dir = os.path.dirname(os.path.realpath(__file__))
Zack Williams6bb2cfe2019-03-27 15:01:45 -070042 template_dir = os.path.join(current_dir, "templates/")
Matteo Scandolo09d469c2017-07-07 11:46:48 -070043
Matteo Scandolo21dde412017-07-11 18:54:12 -070044 app = Klein()
45
Andy Bavier571489f2019-02-05 19:23:51 -070046 def execute_tosca(self, parser):
47 parser.execute()
48 if parser.delete:
49 response_text = "Deleted models: %s" % str(parser.ordered_models_name)
Matteo Scandoloc4680752018-05-17 12:16:30 -070050 else:
Andy Bavier571489f2019-02-05 19:23:51 -070051 response_text = "Created models: %s" % str(parser.ordered_models_name)
Matteo Scandolo1fedfae2017-10-09 13:57:00 -070052 return response_text
53
54 def errorCallback(self, failure, request):
55 request.setResponseCode(500)
Matteo Scandolo21dde412017-07-11 18:54:12 -070056 try:
Matteo Scandolob2eff2c2018-03-02 12:58:10 -080057 f = failure.getErrorMessage()
Scott Baker30c3d752018-10-04 13:08:41 -070058 if f.startswith("XOSPermissionDenied"):
59 request.setResponseCode(401)
Matteo Scandolo5a07a2c2018-06-05 18:04:00 -070060 log.info("[XOS-TOSCA] Error while loading TOSCA: \n\n", failure=f)
Matteo Scandolob2eff2c2018-03-02 12:58:10 -080061 return f
Matteo Scandolo5a07a2c2018-06-05 18:04:00 -070062 except Exception:
63 log.info("[XOS-TOSCA] Fatal Error: \n\n", failure=failure)
Matteo Scandolo1fedfae2017-10-09 13:57:00 -070064 return "Internal server error, please report this along with the failed recipe."
Matteo Scandolo21dde412017-07-11 18:54:12 -070065
Zack Williams6bb2cfe2019-03-27 15:01:45 -070066 @app.route("/", methods=["GET"])
Matteo Scandolo21dde412017-07-11 18:54:12 -070067 def index(self, request):
Matteo Scandolo09d469c2017-07-07 11:46:48 -070068 request.responseHeaders.addRawHeader(b"content-type", b"application/json")
Zack Williams6bb2cfe2019-03-27 15:01:45 -070069 tosca_defs = [f for f in os.listdir(TOSCA_DEFS_DIR) if not f.startswith(".")]
Matteo Scandolo09d469c2017-07-07 11:46:48 -070070
71 response = {}
72 for d in tosca_defs:
Zack Williams6bb2cfe2019-03-27 15:01:45 -070073 name = d.replace(".yaml", "")
Matteo Scandolo09d469c2017-07-07 11:46:48 -070074 response[name] = "/custom_type/%s" % name
75 return json.dumps(response)
Matteo Scandolo21dde412017-07-11 18:54:12 -070076
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070077 @app.route("/custom_type/<name>")
78 def custom_type(self, request, name):
79 request.responseHeaders.addRawHeader(b"content-type", b"text/plain")
Zack Williams6bb2cfe2019-03-27 15:01:45 -070080 custom_type = open(TOSCA_DEFS_DIR + "/" + name + ".yaml").read()
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070081 return custom_type
82
Zack Williams6bb2cfe2019-03-27 15:01:45 -070083 @app.route("/run", methods=["POST"])
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070084 def run(self, request):
Zack Williams6bb2cfe2019-03-27 15:01:45 -070085 return self._handle_post(request, delete=False)
Matteo Scandolo21dde412017-07-11 18:54:12 -070086
Zack Williams6bb2cfe2019-03-27 15:01:45 -070087 @app.route("/delete", methods=["POST"])
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070088 def delete(self, request):
Zack Williams6bb2cfe2019-03-27 15:01:45 -070089 return self._handle_post(request, delete=True)
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -070090
Zack Williams6bb2cfe2019-03-27 15:01:45 -070091 def _handle_post(self, request, delete=False):
92
93 headers = request.getAllHeaders()
94 username = headers["xos-username"]
95 password = headers["xos-password"]
96 recipe = request.content.read()
97
98 parser = TOSCA_Parser(recipe, username, password, delete=delete)
Andy Bavier571489f2019-02-05 19:23:51 -070099 d = GRPC_Client().create_secure_client(username, password, parser)
Matteo Scandolo1fedfae2017-10-09 13:57:00 -0700100 tosca_execution = d.addCallback(self.execute_tosca)
101 tosca_execution.addErrback(self.errorCallback, request)
Matteo Scandolo78ca3eb2017-07-13 16:58:22 -0700102 return d
Matteo Scandolo09d469c2017-07-07 11:46:48 -0700103
Matteo Scandolo9ce18252017-06-22 10:48:25 -0700104 def __init__(self):
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700105 self.app.run("0.0.0.0", "9102")