summaryrefslogtreecommitdiffstats
path: root/app/tosca_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tosca_server.py')
-rw-r--r--app/tosca_server.py532
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()
+
+