X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=httpserver.py;h=5d48beb80393d9d1fcc6600ba1440eeb3c9d7bad;hb=f30a67727909de9df4cc5ea6c213a8795c349aef;hp=870d680247f4f4b398c5a80a2881c86c75ab946f;hpb=2a5a0c5f6604a8dea29bcae20d9a1b2d00bdb8ff;p=osm%2Fopenvim.git diff --git a/httpserver.py b/httpserver.py index 870d680..5d48beb 100644 --- a/httpserver.py +++ b/httpserver.py @@ -26,7 +26,7 @@ This is the thread for the http server North API. Two thread will be launched, with normal and administrative permissions. ''' -__author__="Alfonso Tierno" +__author__="Alfonso Tierno, Gerardo Garcia" __date__ ="$10-jul-2014 12:07:15$" import bottle @@ -37,7 +37,8 @@ import threading import datetime import hashlib import os -import RADclass +import imp +#import only if needed because not needed in test mode. To allow an easier installation import RADclass from jsonschema import validate as js_v, exceptions as js_e import host_thread as ht from vim_schema import host_new_schema, host_edit_schema, tenant_new_schema, \ @@ -50,6 +51,8 @@ from vim_schema import host_new_schema, host_edit_schema, tenant_new_schema, \ global my global url_base global config_dic +global RADclass_module +RADclass=None #RADclass module is charged only if not in test mode url_base="/openvim" @@ -71,6 +74,11 @@ def md5(fname): hash_md5.update(chunk) return hash_md5.hexdigest() +def md5_string(fname): + hash_md5 = hashlib.md5() + hash_md5.update(fname) + return hash_md5.hexdigest() + def check_extended(extended, allow_net_attach=False): '''Makes and extra checking of extended input that cannot be done using jsonschema Attributes: @@ -535,9 +543,14 @@ def http_post_hosts(): ip_name=host['ip_name'] user=host['user'] password=host.get('password', None) + if not RADclass_module: + try: + RADclass_module = imp.find_module("RADclass") + except (IOError, ImportError) as e: + raise ImportError("Cannot import RADclass.py Openvim not properly installed" +str(e)) #fill rad info - rad = RADclass.RADclass() + rad = RADclass_module.RADclass() (return_status, code) = rad.obtain_RAD(user, password, ip_name) #return @@ -599,7 +612,6 @@ def http_post_hosts(): sriov['source_name'] = index index += 1 interfaces.append ({'pci':str(port_k), 'Mbps': port_v['speed']/1000000, 'sriovs': new_sriovs, 'mac':port_v['mac'], 'source_name':port_v['source_name']}) - #@TODO LA memoria devuelta por el RAD es incorrecta, almenos para IVY1, NFV100 memory=node['memory']['node_size'] / (1024*1024*1024) #memory=get_next_2pow(node['memory']['hugepage_nr']) host['numas'].append( {'numa_socket': node['id'], 'hugepages': node['memory']['hugepage_nr'], 'memory':memory, 'interfaces': interfaces, 'cores': cores } ) @@ -1032,13 +1044,14 @@ def http_get_images(tenant_id): bottle.abort(result, content) #obtain data select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_image, - ('id','name','description','path','public') ) + ('id','name','checksum','description','path','public') ) if tenant_id=='any': from_ ='images' + where_or_ = None else: - from_ ='tenants_images inner join images on tenants_images.image_id=images.uuid' - where_['tenant_id'] = tenant_id - result, content = my.db.get_table(SELECT=select_, FROM=from_, WHERE=where_, LIMIT=limit_) + from_ ='tenants_images right join images on tenants_images.image_id=images.uuid' + where_or_ = {'tenant_id': tenant_id, 'public': 'yes'} + result, content = my.db.get_table(SELECT=select_, DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND", LIMIT=limit_) if result < 0: print "http_get_images Error", content bottle.abort(-result, content) @@ -1057,14 +1070,15 @@ def http_get_image_id(tenant_id, image_id): bottle.abort(result, content) #obtain data select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_image, - ('id','name','description','progress', 'status','path', 'created', 'updated','public') ) + ('id','name','checksum','description','progress', 'status','path', 'created', 'updated','public') ) if tenant_id=='any': from_ ='images' + where_or_ = None else: - from_ ='tenants_images as ti inner join images as i on ti.image_id=i.uuid' - where_['tenant_id'] = tenant_id + from_ ='tenants_images as ti right join images as i on ti.image_id=i.uuid' + where_or_ = {'tenant_id': tenant_id, 'public': "yes"} where_['uuid'] = image_id - result, content = my.db.get_table(SELECT=select_, FROM=from_, WHERE=where_, LIMIT=limit_) + result, content = my.db.get_table(SELECT=select_, DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND", LIMIT=limit_) if result < 0: print "http_get_images error %d %s" % (result, content) @@ -1099,15 +1113,26 @@ def http_post_images(tenant_id): if metadata_dict is not None: http_content['image']['metadata'] = json.dumps(metadata_dict) #calculate checksum - host_test_mode = True if config_dic['mode']=='test' or config_dic['mode']=="OF only" else False try: image_file = http_content['image'].get('path',None) - if os.path.exists(image_file): - http_content['image']['checksum'] = md5(image_file) - elif is_url(image_file): + parsed_url = urlparse.urlparse(image_file) + if parsed_url.scheme == "" and parsed_url.netloc == "": + # The path is a local file + if os.path.exists(image_file): + http_content['image']['checksum'] = md5(image_file) + else: + # The path is a URL. Code should be added to download the image and calculate the checksum + #http_content['image']['checksum'] = md5(downloaded_image) pass + # Finally, only if we are in test mode and checksum has not been calculated, we calculate it from the path + host_test_mode = True if config_dic['mode']=='test' or config_dic['mode']=="OF only" else False + if host_test_mode: + if 'checksum' not in http_content['image']: + http_content['image']['checksum'] = md5_string(image_file) else: - if not host_test_mode: + # At this point, if the path is a local file and no chechsum has been obtained yet, an error is sent back. + # If it is a URL, no error is sent. Checksum will be an empty string + if parsed_url.scheme == "" and parsed_url.netloc == "" and 'checksum' not in http_content['image']: content = "Image file not found" print "http_post_images error: %d %s" % (HTTP_Bad_Request, content) bottle.abort(HTTP_Bad_Request, content) @@ -1218,10 +1243,11 @@ def http_put_image_id(tenant_id, image_id): where_={'uuid': image_id} if tenant_id=='any': from_ ='images' + where_or_ = None else: - from_ ='tenants_images as ti inner join images as i on ti.image_id=i.uuid' - where_['tenant_id'] = tenant_id - result, content = my.db.get_table(SELECT=('public',), FROM=from_, WHERE=where_) + from_ ='tenants_images as ti right join images as i on ti.image_id=i.uuid' + where_or_ = {'tenant_id': tenant_id, 'public': 'yes'} + result, content = my.db.get_table(SELECT=('public',), DISTINCT=True, FROM=from_, WHERE=where_, WHERE_OR=where_or_, WHERE_AND_OR="AND") if result==0: text_error="Image '%s' not found" % image_id if tenant_id!='any': @@ -1349,8 +1375,9 @@ def http_post_server_id(tenant_id): return server['flavor']=content[0] #check image valid and take info - result, content = my.db.get_table(FROM='tenants_images as ti join images as i on ti.image_id=i.uuid', - SELECT=('path','metadata'), WHERE={'uuid':server['image_id'], 'tenant_id':tenant_id, "status":"ACTIVE"}) + result, content = my.db.get_table(FROM='tenants_images as ti right join images as i on ti.image_id=i.uuid', + SELECT=('path','metadata'), WHERE={'uuid':server['image_id'], "status":"ACTIVE"}, + WHERE_OR={'tenant_id':tenant_id, 'public': 'yes'}, WHERE_AND_OR="AND", DISTINCT=True) if result<=0: bottle.abort(HTTP_Not_Found, 'image_id %s not found or not ACTIVE' % server['image_id']) return @@ -1492,8 +1519,9 @@ def http_server_action(server_id, tenant_id, action): else: #result==1 image_id = content[0]['image_id'] - result, content = my.db.get_table(FROM='tenants_images as ti join images as i on ti.image_id=i.uuid', - SELECT=('path','metadata'), WHERE={'uuid':image_id, 'tenant_id':tenant_id, "status":"ACTIVE"}) + result, content = my.db.get_table(FROM='tenants_images as ti right join images as i on ti.image_id=i.uuid', + SELECT=('path','metadata'), WHERE={'uuid':image_id, "status":"ACTIVE"}, + WHERE_OR={'tenant_id':tenant_id, 'public': 'yes'}, WHERE_AND_OR="AND", DISTINCT=True) if result<=0: bottle.abort(HTTP_Not_Found, 'image_id %s not found or not ACTIVE' % image_id) return