diff options
Diffstat (limited to 'app/tosca_server.py')
-rw-r--r-- | app/tosca_server.py | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/app/tosca_server.py b/app/tosca_server.py new file mode 100644 index 0000000..0836d3a --- /dev/null +++ b/app/tosca_server.py @@ -0,0 +1,532 @@ +''' +Created on Apr 8, 2016 + +@author: Shu Shi +''' +#!/usr/bin/env python +import web +import json, os, sys +import base64 +from toscalib.tosca_workbook import ToscaWorkBook +from toscalib.tosca_builder import ToscaBuilder +from toscalib.templates.database import ToscaDB +from version import __version__ + + +# class fe_get_itembyid: +# def GET(self): +# item_id = web.input() +# print( 'get_itembyid is called with input: ' + str(item_id)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_get_template: +# def GET(self): +# temp_id = web.input() +# print( 'get_template is called with input: ' + str(temp_id)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_get_type: +# def GET(self): +# type_name = web.input() +# print( 'get_type is called with input: ' + str(type_name)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_get_compositioncreate: +# def GET(self): +# webinput = web.input(cid='unknown_cid') +# print( 'get_compositioncreate is called with input: ' + str(webinput)) +# cid = webinput.cid +# +# workbook_db = ToscaDB() +# +# if cid not in workbook_db: +# workbook_db[cid] = ToscaWorkBook() +# +# ret_json = workbook_db[cid].toJson() +# ret_json['cid'] = cid +# +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# +# print( 'get_compositioncreate returns:' + ret_json) +# return json.dumps(ret_json) +# +# class fe_get_ice: +# def GET(self): +# input_list = web.input() +# print( 'get_ice is called with input: ' + str(input_list)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_compimg: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_compimg is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_compimg input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_commit: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_commit is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_commit input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_set_nodepolicies: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_set_nodepolicies is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_set_nodepolicies input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_add_node: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# webinput = web.input(cid='unknown_cid') +# print( 'post_composition_add_node is called with input: ' + str(webinput)) +# cid = webinput.cid +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_add_node input json data: ' + str(in_data)) +# +# workbook_db = ToscaDB() +# if cid not in workbook_db: +# workbook_db[cid] = ToscaWorkBook() +# +# if 'type' in in_data: +# if 'name' in in_data['type']: +# print( 'add node type: ' + in_data['type']['name']) +# new_node = workbook_db[cid]._use(in_data['type']['name']) +# new_node.fe_json = in_data +# if 'nid' in in_data: +# new_node.fe_nid = in_data['nid'] +# else: +# print( 'in_data has type but no name') +# else: +# print( 'in_data has no type') +# +# +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# +# return json.dumps(in_data) +# +# class fe_post_composition_update_nodes: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# webinput = web.input(cid='unknown_cid') +# print( 'post_composition_update_nodes is called with input: ' + str(webinput)) +# cid = webinput.cid +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_update_nodes input json data: ' + str(in_data)) +# +# workbook_db = ToscaDB() +# +# if cid not in workbook_db: +# workbook_db[cid] = ToscaWorkBook() +# +# for in_item in in_data: +# if 'nid' in in_item : +# for node in workbook_db[cid].template.node_dict.itervalues(): +# if node.fe_nid == in_data['nid']: +# node.fe_json.update(in_item) +# break +# else: +# print( 'one item has no nid') +# +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_delete_node: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_delete_nodes is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_delete_nodes input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_add_relation: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_add_relation is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_add_relation input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_delete_relation: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_delete_relation is called with input: ' + str(cid)) +# in_data = json.loads(web.data()) +# print( 'post_composition_delete_relation input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_add_inputs: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_add_inputs is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_add_inputs input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_add_outputs: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_add_outputs is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_add_outputs input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class fe_post_composition_set_node_properties: +# def OPTIONS(self): +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return '' +# def POST(self): +# cid = web.input() +# print( 'post_composition_set_node_properties is called with input: ' + str(cid)) +# try: +# in_data = json.loads(web.data()) +# except ValueError as e: +# in_data = web.data() +# print( 'post_composition_set_node_properties input json data: ' + str(in_data)) +# web.header('Content-Type', 'application/json') +# web.header('Access-Control-Allow-Origin', '*') +# web.header('Access-Control-Allow-Headers', 'Origin, Content-Type, X-Auth-Token') +# return json.dumps({}) +# +# class upload: +# def POST(self, dir): +# # data = json.loads(web.data()) +# # pyDict = {'one':1,'two':2} +# # web.header('Content-Type', 'application/json') +# # return json.dumps(pyDict) +# return 'OK' +# +# class import_file: +# def GET(self): +# user_data = web.input(dir='') +# file_dir = user_data.dir +# if 'name' not in user_data: +# return 'Error: input has no file name' +# file_name = user_data.name +# workbook = ToscaWorkBook() +# workbook._import( file_dir +'/'+ file_name) +# return 'OK' +# +# class use: +# def GET(self): +# user_data = web.input() +# if 'type' not in user_data or 'name' not in user_data: +# return 'Error: input has no type or name' +# use_type = user_data['type'] +# name = user_data['name'] +# +# workbook = ToscaWorkBook() +# +# workbook._use(name) +# return 'OK' +# +# class assign: +# def GET(self): +# user_data = web.input() +# if 'src_node') is False or user_data.has_key('value') is False: +# return 'Error: input has no src_node or value' +# src = user_data.src_node +# dst_val = user_data.value +# +# sub2 = None +# if user_data.has_key('property'): +# sub = user_data.property +# elif user_data.has_key('capability'): +# sub = user_data.capability +# if user_data.has_key('capability_property') is False: +# return "Error: input has capability but no capability_property" +# else: +# sub2 = user_data.capability_property +# elif user_data.has_key('requirement'): +# sub = user_data.requirement +# +# workbook = ToscaWorkBook() +# +# if sub2 is None: +# workbook._assign(src, sub, dst_val) +# else: +# workbook._assign(src, sub, sub2, dst_val) +# +# return 'OK' +# +# class clear: +# def GET(self): +# workbook = ToscaWorkBook() +# +# workbook._reset() +# return 'OK' +# +# class show: +# def GET(self): +# user_data = web.input(level='details') +# workbook = ToscaWorkBook() +# +# if user_data.level == 'details': +# return workbook._show_details() +# else: +# return workbook._show_abstract() +# +# class export: +# def GET(self): +# user_data = web.input(type='tosca', translation='off') +# workbook = ToscaWorkBook() +# +# if user_data.translation == 'on': +# if user_data.has_key('translation_lib'): +# tran_lib = user_data.translation_lib +# workbook._load_translation_db(tran_lib) +# +# if user_data.type == 'tosca': +# return workbook._export_yaml_web() +# elif user_data.type == 'heat': +# return +# else: +# return 'Error in export type: only tosca or heat are supported' + +class translate_template: + def POST(self): + try: + in_data = json.loads(web.data().decode('utf-8')) + except ValueError as e: + in_data = web.data() + print( 'translate_template input json data: ' + str(in_data)) + + workbook = ToscaWorkBook() + workbook._import_dir('./data/shared_model/') +# workbook._load_translation_db('./data/shared_model/') + + if 'models' in in_data: + in_model = in_data['models'] + if type(in_model) != list: + print( 'models in the input should be a list type') + for model_entry in in_model: + for key in ['schema', 'template', 'translate']: + if key in model_entry: + workbook._import_yml_str(base64.b64decode(model_entry[key])) + + if 'template' in in_data: + in_temp = in_data['template'] + workbook._translate_template_yaml_str(base64.b64decode(in_temp)) + workbook._add_shared_node([{'dcae.capabilities.cdapHost':'cdap_host'}, {'dcae.capabilities.dockerHost': 'docker_host'}, {'dcae.capabilities.composition.host': 'composition_virtual'}]) + + ret = workbook._export_yaml_web('cloudify,main') + print(ret) + return ret + +class model_create: + def POST(self): + try: + in_data = json.loads(web.data().decode('utf-8')) + except ValueError as e: + in_data = web.data() + print( 'model_create input json data: ' + str(in_data)) + + ret = {} + if 'spec' in in_data: + spec_str = in_data['spec'] + model_prefix = './data/tosca_model' + meta_model = './data/meta_model/meta_tosca_schema.yaml' + + builder = ToscaBuilder() + + builder.import_schema(meta_model) + builder.import_spec_str(spec_str) + name = builder.spec_import.name + builder.create_node_type() + + filename = model_prefix + '/'+ name + '/schema.yaml' + dirname = os.path.dirname(filename) + try: + os.stat(dirname) + except: + os.mkdir(dirname) + + schema_str = builder.export_schema(model_prefix+'/' + name + '/schema.yaml') + builder.import_schema(model_prefix+'/' + name + '/schema.yaml') + builder.create_model(name) + template_str = builder.export_model(model_prefix+'/' + name + '/template.yaml') + builder.create_translate(name) + translate_str = builder.export_translation(model_prefix+'/' + name + '/translate.yaml') + + ret['schema'] = (base64.encodestring(bytes(schema_str, 'utf-8'))).decode('utf-8') + ret['template'] = base64.encodestring(bytes(template_str, 'utf-8')).decode('utf-8') + ret['translate'] = base64.encodestring(bytes(translate_str, 'utf-8')).decode('utf-8') + + return json.dumps(ret) + + +# Story 318043 - The TOSCA Lab server should expose API for healthcheck with response: +# { +# "healthCheckComponent": "TOSCA_LAB", +# "healthCheckStatus": "<UP / DOWN>", +# "version": "<component version>", +# "description": "<OK or error description>" +# } +class health_check: + def GET(self): + ret = dict() + ret['healthCheckComponent'] = "TOSCA_LAB" + ret['healthCheckStatus'] = "UP" + ret['version'] = __version__ + ret['description'] = "OK" + print ('TOSCA_LAB got healthcheck request and returns' + str(ret)) + return json.dumps(ret) + + +class MyApplication(web.application): + def run(self, port=8080, *middleware): + func = self.wsgifunc(*middleware) + return web.httpserver.runsimple(func, ('0.0.0.0', port)) + +urls = ( + '/upload/(.*)', 'upload', + '/import', 'import_file', #/import?dir=xxx&name=xxx + '/use', 'use', #/use?type=xxx&name=xxx + '/assign', 'assign', #/assign?src_node=xxx&[property|capability|requrement]=xxx&[capability_property=xxx]&value]xxx + '/clear', 'clear', #/clear + '/show', 'show', #/show?[level=abstract/details] + '/export', 'export', #/export?[type=tosca/heat]&[translation=[on|off]]&[translation_lib=xxx] + '/itembyid', 'fe_get_itembyid', + '/template', 'fe_get_template', + '/type', 'fe_get_type', + '/compositioncreate', 'fe_get_compositioncreate', + '/ice.html', 'fe_get_ice', + '/compimg', 'fe_post_compimg', + '/composition.commit', 'fe_post_composition_commit', + '/composition.setnodepolicies', 'fe_post_composition_set_nodepolicies', + '/composition.addnode', 'fe_post_composition_add_node', + '/composition.updatenodes', 'fe_post_composition_update_nodes', + '/composition.deletenode', 'fe_post_composition_delete_node', + '/composition.addrelation', 'fe_post_composition_add_relation', + '/composition.deleterelation', 'fe_post_composition_delete_relation', + '/composition.addinputs', 'fe_post_composition_add_inputs', + '/composition.addoutputs', 'fe_post_composition_add_outputs', + '/composition.setnodeproperties', 'fe_post_composition_set_node_properties', + '/translate', 'translate_template', + '/model_create', 'model_create', + '/healthcheck', 'health_check') + +application = web.application(urls, globals(), autoreload=False).wsgifunc() + + +if __name__ == "__main__": + app = MyApplication(urls, globals()) + if len(sys.argv) > 1: + app.run(int(sys.argv[1])) + else: + app.run() + + |