X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=httpserver.py;h=6a16f39de20e61b77a6694e9e44fc929546205f2;hb=f9a1a8d51e7525f0d4acfe02dcb7fb8696fc20b0;hp=2380d039f7875142690cc72485511f1752db6bdb;hpb=9e194594e2dbc4419e13e4c89ddc0e5d639723fd;p=osm%2Fopenvim.git diff --git a/httpserver.py b/httpserver.py index 2380d03..6a16f39 100644 --- a/httpserver.py +++ b/httpserver.py @@ -47,7 +47,7 @@ from vim_schema import host_new_schema, host_edit_schema, tenant_new_schema, \ flavor_new_schema, flavor_update_schema, \ image_new_schema, image_update_schema, \ server_new_schema, server_action_schema, network_new_schema, network_update_schema, \ - port_new_schema, port_update_schema, openflow_controller_schema + port_new_schema, port_update_schema, openflow_controller_schema, of_port_map_new_schema import ovim import logging @@ -147,6 +147,7 @@ def check_extended(extended, allow_net_attach=False): # # dictionaries that change from HTTP API to database naming # +http2db_id={'id':'uuid'} http2db_host={'id':'uuid'} http2db_tenant={'id':'uuid'} http2db_flavor={'id':'uuid','imageRef':'image_id'} @@ -861,114 +862,140 @@ def http_delete_host_id(host_id): print "http_delete_host_id error",result, content bottle.abort(-result, content) return - - - # # TENANTS # + @bottle.route(url_base + '/tenants', method='GET') def http_get_tenants(): - my = config_dic['http_threads'][ threading.current_thread().name ] - select_,where_,limit_ = filter_query_string(bottle.request.query, http2db_tenant, - ('id','name','description','enabled') ) - result, content = my.db.get_table(FROM='tenants', SELECT=select_,WHERE=where_,LIMIT=limit_) - if result < 0: - print "http_get_tenants Error", content - bottle.abort(-result, content) - else: - change_keys_http2db(content, http2db_tenant, reverse=True) - convert_boolean(content, ('enabled',)) - data={'tenants' : content} - #data['tenants_links'] = dict([('tenant', row['id']) for row in content]) + """ + Retreive tenant list from DB + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + select_, where_, limit_ = filter_query_string(bottle.request.query, http2db_tenant, + ('id', 'name', 'description', 'enabled')) + tenants = my.ovim.get_tenants(select_, where_) + delete_nulls(tenants) + change_keys_http2db(tenants, http2db_tenant, reverse=True) + data = {'tenants': tenants} return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) + @bottle.route(url_base + '/tenants/', method='GET') def http_get_tenant_id(tenant_id): - my = config_dic['http_threads'][ threading.current_thread().name ] - result, content = my.db.get_table(FROM='tenants', SELECT=('uuid','name','description', 'enabled'),WHERE={'uuid': tenant_id} ) - if result < 0: - print "http_get_tenant_id error %d %s" % (result, content) - bottle.abort(-result, content) - elif result==0: - print "http_get_tenant_id tenant '%s' not found" % tenant_id - bottle.abort(HTTP_Not_Found, "tenant %s not found" % tenant_id) - else: - change_keys_http2db(content, http2db_tenant, reverse=True) - convert_boolean(content, ('enabled',)) - data={'tenant' : content[0]} - #data['tenants_links'] = dict([('tenant', row['id']) for row in content]) + """ + Get tenant from DB by id + :param tenant_id: tenant id + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + tenant = my.ovim.show_tenant_id(tenant_id) + delete_nulls(tenant) + change_keys_http2db(tenant, http2db_tenant, reverse=True) + data = {'tenant': tenant} return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) @bottle.route(url_base + '/tenants', method='POST') def http_post_tenants(): - '''insert a tenant into the database.''' - my = config_dic['http_threads'][ threading.current_thread().name ] - #parse input data - http_content = format_in( tenant_new_schema ) - r = remove_extra_items(http_content, tenant_new_schema) - if r is not None: print "http_post_tenants: Warning: remove extra items ", r - change_keys_http2db(http_content['tenant'], http2db_tenant) + """ + Insert a tenant into the database. + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + http_content = format_in(tenant_new_schema) + r = remove_extra_items(http_content, tenant_new_schema) + if r is not None: + my.logger.error("http_post_tenants: Warning: remove extra items " + str(r), exc_info=True) + # insert in data base + tenant_id = my.ovim.new_tentant(http_content['tenant']) + tenant = my.ovim.show_tenant_id(tenant_id) + change_keys_http2db(tenant, http2db_tenant, reverse=True) + delete_nulls(tenant) + data = {'tenant': tenant} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) - #insert in data base - result, content = my.db.new_tenant(http_content['tenant']) - - if result >= 0: - return http_get_tenant_id(content) - else: - bottle.abort(-result, content) - return @bottle.route(url_base + '/tenants/', method='PUT') def http_put_tenant_id(tenant_id): - '''update a tenant into the database.''' - my = config_dic['http_threads'][ threading.current_thread().name ] - #parse input data - http_content = format_in( tenant_edit_schema ) - r = remove_extra_items(http_content, tenant_edit_schema) - if r is not None: print "http_put_tenant_id: Warning: remove extra items ", r - change_keys_http2db(http_content['tenant'], http2db_tenant) + """ + Update a tenantinto DB. + :param tenant_id: tentant id + :return: + """ + + my = config_dic['http_threads'][threading.current_thread().name] + try: + # parse input data + http_content = format_in(tenant_edit_schema) + r = remove_extra_items(http_content, tenant_edit_schema) + if r is not None: + print "http_put_tenant_id: Warning: remove extra items ", r + change_keys_http2db(http_content['tenant'], http2db_tenant) + # insert in data base + my.ovim.edit_tenant(tenant_id, http_content['tenant']) + tenant = my.ovim.show_tenant_id(tenant_id) + change_keys_http2db(tenant, http2db_tenant, reverse=True) + data = {'tenant': tenant} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) - #insert in data base - result, content = my.db.update_rows('tenants', http_content['tenant'], WHERE={'uuid': tenant_id}, log=True ) - if result >= 0: - return http_get_tenant_id(tenant_id) - else: - bottle.abort(-result, content) - return @bottle.route(url_base + '/tenants/', method='DELETE') def http_delete_tenant_id(tenant_id): - my = config_dic['http_threads'][ threading.current_thread().name ] - #check permissions - r, tenants_flavors = my.db.get_table(FROM='tenants_flavors', SELECT=('flavor_id','tenant_id'), WHERE={'tenant_id': tenant_id}) - if r<=0: - tenants_flavors=() - r, tenants_images = my.db.get_table(FROM='tenants_images', SELECT=('image_id','tenant_id'), WHERE={'tenant_id': tenant_id}) - if r<=0: - tenants_images=() - result, content = my.db.delete_row('tenants', tenant_id) - if result == 0: - bottle.abort(HTTP_Not_Found, content) - elif result >0: - print "alf", tenants_flavors, tenants_images - for flavor in tenants_flavors: - my.db.delete_row_by_key("flavors", "uuid", flavor['flavor_id']) - for image in tenants_images: - my.db.delete_row_by_key("images", "uuid", image['image_id']) - data={'result' : content} - return format_out(data) - else: - print "http_delete_tenant_id error",result, content - bottle.abort(-result, content) - return + """ + Delete a tenant from the database. + :param tenant_id: tenant id + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + try: + content = my.ovim.delete_tentant(tenant_id) + data = {'result': content} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) # # FLAVORS # + @bottle.route(url_base + '//flavors', method='GET') def http_get_flavors(tenant_id): my = config_dic['http_threads'][ threading.current_thread().name ] @@ -1592,14 +1619,18 @@ def http_post_server_id(tenant_id): r,c = config_dic['host_threads'][ server['host_id'] ].insert_task( 'restore-iface',*port ) if r < 0: print ' http_post_servers ERROR RESTORE IFACE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c - #updata nets - for net in nets: - r,c = config_dic['of_thread'].insert_task("update-net", net) - if r < 0: - print ':http_post_servers ERROR UPDATING NETS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c - - - #look for dhcp ip address + # update nets + for net_id in nets: + try: + my.ovim.net_update_ofc_thread(net_id) + except ovim.ovimException as e: + raise ovim.ovimException("http_post_servers, Error updating network with id '{}', '{}'". + format(net_id, str(e)), HTTP_Internal_Server_Error) + except Exception as e: + raise ovim.ovimException("http_post_servers, Error updating network with id '{}', '{}'". + format(net_id, str(e)), HTTP_Internal_Server_Error) + + # look for dhcp ip address r2, c2 = my.db.get_table(FROM="ports", SELECT=["mac", "ip_address", "net_id"], WHERE={"instance_id": new_instance}) if r2 >0: for iface in c2: @@ -1779,12 +1810,20 @@ def http_server_action(server_id, tenant_id, action): if r1 < 0: print ' http_post_server_action error at server deletion ERROR resore-iface !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c1 data={'result' : 'deleting in process, but ifaces cannot be restored!!!!!'} - for net in nets: - r1,c1 = config_dic['of_thread'].insert_task("update-net", net) - if r1 < 0: - print ' http_post_server_action error at server deletion ERROR UPDATING NETS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + c1 - data={'result' : 'deleting in process, but openflow rules cannot be deleted!!!!!'} - #look for dhcp ip address + for net_id in nets: + try: + my.ovim.net_update_ofc_thread(net_id) + except ovim.ovimException as e: + raise ovim.ovimException("http_post_servers, Error updating network with id '{}', '{}'". + format(net_id, str(e)), HTTP_Internal_Server_Error) + except Exception as e: + raise ovim.ovimException("http_post_server_action error at server deletion " + "ERROR UPDATING NET '{}', '{}'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!". + format(net_id, str(e)), HTTP_Internal_Server_Error) + + data = {'result': 'deleting in process, but openflow rules cannot be deleted!!!!!'} + + # look for dhcp ip address if r2 >0 and config_dic.get("dhcp_server"): for iface in c2: if iface["net_id"] in config_dic["dhcp_nets"]: @@ -1946,7 +1985,7 @@ def http_put_network_id(network_id): http_content = format_in(network_update_schema) change_keys_http2db(http_content['network'], http2db_network) network = http_content['network'] - return my.ovim.edit_network(network_id, network) + return format_out(my.ovim.edit_network(network_id, network)) except ovim.ovimException as e: my.logger.error(str(e), exc_info=True) @@ -2157,9 +2196,9 @@ def http_put_openflow_id(network_id): data = {'result': str(result) + " nets updates"} return format_out(data) - +@bottle.route(url_base + '/networks/clear/openflow/', method='DELETE') @bottle.route(url_base + '/networks/clear/openflow', method='DELETE') -def http_clear_openflow_rules(): +def http_clear_openflow_rules(ofc_id=None): """ To make actions over the net. The action is to delete ALL openflow rules :return: @@ -2169,7 +2208,7 @@ def http_clear_openflow_rules(): if not my.admin: bottle.abort(HTTP_Unauthorized, "Needed admin privileges") try: - my.ovim.delete_openflow_rules() + my.ovim.delete_openflow_rules(ofc_id) except ovim.ovimException as e: my.logger.error(str(e), exc_info=True) bottle.abort(e.http_code, str(e)) @@ -2180,16 +2219,25 @@ def http_clear_openflow_rules(): data = {'result': " Clearing openflow rules in process"} return format_out(data) - +@bottle.route(url_base + '/networks/openflow/ports/', method='GET') @bottle.route(url_base + '/networks/openflow/ports', method='GET') -def http_get_openflow_ports(): +def http_get_openflow_ports(ofc_id=None): """ Obtain switch ports names of openflow controller :return: """ my = config_dic['http_threads'][threading.current_thread().name] - ports = my.ovim.get_openflow_ports() - data = {'ports': ports} + + try: + ports = my.ovim.get_openflow_ports(ofc_id) + data = {'ports': ports} + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) + return format_out(data) # # PORTS @@ -2314,3 +2362,78 @@ def http_delete_port_id(port_id): bottle.abort(HTTP_Bad_Request, str(e)) +@bottle.route(url_base + '/openflow/mapping', method='POST') +def http_of_port_mapping(): + """ + Insert a tenant into the database. + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + http_content = format_in(of_port_map_new_schema) + r = remove_extra_items(http_content, of_port_map_new_schema) + if r is not None: + my.logger.error("http_of_port_mapping: Warning: remove extra items " + str(r), exc_info=True) + + # insert in data base + port_mapping = my.ovim.set_of_port_mapping(http_content['of_port_mapings']) + change_keys_http2db(port_mapping, http2db_id, reverse=True) + delete_nulls(port_mapping) + data = {'of_port_mappings': port_mapping} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) + + +@bottle.route(url_base + '/openflow/mapping', method='GET') +def get_of_port_mapping(): + """ + Insert a tenant into the database. + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + select_, where_, limit_ = filter_query_string(bottle.request.query, http2db_id, + ('id', 'ofc_id', 'region', 'compute_node', 'pci', + 'switch_dpid', 'switch_port', 'switch_mac')) + # insert in data base + port_mapping = my.ovim.get_of_port_mappings(select_, where_) + change_keys_http2db(port_mapping, http2db_id, reverse=True) + delete_nulls(port_mapping) + data = {'of_port_mappings': port_mapping} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) + + +@bottle.route(url_base + '/openflow/mapping/', method='DELETE') +def delete_of_port_mapping(region): + """ + Insert a tenant into the database. + :return: + """ + my = config_dic['http_threads'][threading.current_thread().name] + + try: + # insert in data base + db_filter = {'region': region} + result = my.ovim.clear_of_port_mapping(db_filter) + data = {'result': result} + return format_out(data) + except ovim.ovimException as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(e.http_code, str(e)) + except Exception as e: + my.logger.error(str(e), exc_info=True) + bottle.abort(HTTP_Bad_Request, str(e)) +