def delete_slice(sliceid, **kwargs): ''' Delete the slice with id sliceid. @param slice_id: an int that uniquely identifies the slice at the Clearinghouseclearinghouse. @type sliceid: int @param kwargs: will contain additional useful information about the request. Of most use are the items in the C{kwargs['request'].META} dict. These include 'REMOTE_USER' which is the username of the user connecting or if using x509 certs then the domain name. @return error message if there are any errors or "" otherwise. ''' try: single_exp = Experiment.objects.get(slice_id=sliceid) except Experiment.DoesNotExist: return "Experiment Doesnot Exist" fv = FVServerProxy.objects.all()[0] try: success = fv.proxy.api.deleteSlice(single_exp.get_fv_slice_name()) except Exception, e: import traceback traceback.print_exc() if "slice does not exist" in str(e): success = True else: print e return "Couldn't delete slice on flowvisor: %s" % parseFVexception( e)
def delete_slice(slice_id, options={}, **kwargs): ''' Delete the slice with id sliceid. @param slice_id: an int that uniquely identifies the slice at the Clearinghouseclearinghouse. @type slice_id: int @param options: will contain additional useful information for this operation. @type options: dict @param kwargs: will contain additional useful information about the request. Of most use are the items in the C{kwargs['request'].META} dict. These include 'REMOTE_USER' which is the username of the user connecting or if using x509 certs then the domain name. @return error message if there are any errors or "" otherwise. ''' # Determine slice style naming: legacy (Opt-in <= 0.7) or newer (FlowVisor >= 1.0) is_legacy_slice = True # Retrieve information for current Experiment first try: # Legacy slices with older slice naming (Opt-in <= 0.7) single_exp = Experiment.objects.get( slice_id=options["legacy_slice_id"]) if not single_exp: raise Exception except: try: try: uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False single_exp = Experiment.objects.get(slice_id=slice_id) except: is_legacy_slice = True single_exp = Experiment.objects.get(slice_id=slice_id) # New slice naming style (for FlowVisor >= 1.0) -> No legacy slice single_exp = Experiment.objects.get(slice_id=slice_id) except Experiment.DoesNotExist: return "Experiment does not exist" fv = FVServerProxy.objects.all()[0] try: # Legacy slices: use combination of name and ID if is_legacy_slice: old_fv_name = single_exp.get_fv_slice_name() # Otherwise, use UUID else: old_fv_name = single_exp.slice_id success = fv.proxy.api.deleteSlice(old_fv_name) except Exception, e: import traceback traceback.print_exc() if "slice does not exist" in str(e): success = True else: return "Could not delete slice on Flowvisor: %s" % parseFVexception( e)
def delete_slice(slice_id, options={}, **kwargs): ''' Delete the slice with id sliceid. @param slice_id: an int that uniquely identifies the slice at the Clearinghouseclearinghouse. @type slice_id: int @param options: will contain additional useful information for this operation. @type options: dict @param kwargs: will contain additional useful information about the request. Of most use are the items in the C{kwargs['request'].META} dict. These include 'REMOTE_USER' which is the username of the user connecting or if using x509 certs then the domain name. @return error message if there are any errors or "" otherwise. ''' # Determine slice style naming: legacy (Opt-in <= 0.7) or newer (FlowVisor >= 1.0) is_legacy_slice = True # Retrieve information for current Experiment first try: # Legacy slices with older slice naming (Opt-in <= 0.7) single_exp = Experiment.objects.get(slice_id = options["legacy_slice_id"]) if not single_exp: raise Exception except: try: try: uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False single_exp = Experiment.objects.get(slice_id = slice_id) except: is_legacy_slice = True single_exp = Experiment.objects.get(slice_id = slice_id) # New slice naming style (for FlowVisor >= 1.0) -> No legacy slice single_exp = Experiment.objects.get(slice_id = slice_id) except Experiment.DoesNotExist: return "Experiment does not exist" fv = FVServerProxy.objects.all()[0] try: # Legacy slices: use combination of name and ID if is_legacy_slice: old_fv_name = single_exp.get_fv_slice_name() # Otherwise, use UUID else: old_fv_name = single_exp.slice_id success = fv.proxy.api.deleteSlice(old_fv_name) except Exception,e: import traceback traceback.print_exc() if "slice does not exist" in str(e): success = True else: return "Could not delete slice on Flowvisor: %s" % parseFVexception(e)
def get_links(**kwargs): ''' Return what the FlowVisor gives. ''' complete_list = [] fv = FVServerProxy.objects.all()[0] try: links = fv.get_links() except Exception,e: import traceback traceback.print_exc() raise Exception(parseFVexception(e))
def get_links(**kwargs): ''' Return what the FlowVisor gives. ''' complete_list = [] fv = FVServerProxy.objects.all()[0] try: links = fv.get_links() except Exception, e: import traceback traceback.print_exc() raise Exception(parseFVexception(e))
def change_slice_controller(slice_id, controller_url, **kwargs): ''' Changes the slice controller url. ''' complete_list = [] fv = FVServerProxy.objects.all()[0] try: params = controller_url.split(':') experiment = Experiment.objects.get(slice_id = slice_id) slice_name= experiment.get_fv_slice_name() fv.proxy.api.changeSlice(slice_name,'controller_hostname', params[1]) fv.proxy.api.changeSlice(slice_name,'controller_port', params[2]) experiment.controller_url = controller_url except Exception, exc: import traceback traceback.print_exc() raise Exception(parseFVexception(exc,"FV could not update slice controller URL:"))
def change_slice_controller(slice_id, controller_url, **kwargs): ''' Changes the slice controller url. ''' complete_list = [] fv = FVServerProxy.objects.all()[0] try: params = controller_url.split(':') experiment = Experiment.objects.get(slice_id=slice_id) slice_name = experiment.get_fv_slice_name() fv.proxy.api.changeSlice(slice_name, 'controller_hostname', params[1]) fv.proxy.api.changeSlice(slice_name, 'controller_port', params[2]) experiment.controller_url = controller_url except Exception, exc: import traceback traceback.print_exc() raise Exception( parseFVexception(exc, "FV could not update slice controller URL:"))
def create_slice(slice_id, project_name, project_description, slice_name, slice_description, controller_url, owner_email, owner_password, switch_slivers, options={}, **kwargs): ''' Create an OpenFlow slice. The C{switch_sliver} list contains a dict for each switch to be added to the slice's topology. Each such dict has the following items: - C{datapath_id}: the switch's datapath id - C{flowspace}: an array of dicts describing the switch's flowspace Each such dict has the following keys: - C{id}: integer. Per clearinghouse unique identifier for the rule. - C{port_num_start}, C{port_num_end}: string. the port range for this flowspace - C{dl_src_start}, C{dl_src_end}: string. link layer address range in "xx:xx:xx:xx:xx:xx" format or '*' for wildcard - C{dl_dst_start}, C{dl_dst_end}: string. link layer address range in "xx:xx:xx:xx:xx:xx" format or '*' for wildcard - C{vlan_id_start}, C{vlan_id_end}: string. vlan id range or "*" for wildcard - C{nw_src_start}, C{nw_src_end}: string. network address range in "x.x.x.x" format or '*' for wildcard - C{nw_dst_start}, C{nw_dst_end}: string. network address range in "x.x.x.x" format or '*' for wildcard - C{nw_proto_start}, C{nw_proto_end}: string. network protocol range or "*" for wildcard - C{tp_src_start}, C{tp_src_end}: string. transport port range or "*" for wildcard - C{tp_dst_start}, C{tp_dst_end}: string. transport port range or "*" for wildcard The call returns a dict with the following items: - C{error_msg}: a summary error message or "" if no errors occurred. - C{switches}: a list of dicts with the following items: - C{datapath_id}: id of the switch that caused the error - C{error}: optional error msg for the switch - all other fields of the C{switch_sliver} dicts mentioned above (port_num, direction, ...). The values for these items are the error messages associated with each field. @param slice_id: a string that uniquely identifies the slice at the clearinghouse. @type slice_id: int @param project_name: a name for the project under which this slice is created @type project_name: string @param project_description: text describing the project @type project_description: string @param slice_name: Name for the slice @type slice_name: string @param slice_description: text describing the slice/experiment @type slice_description: string @param controller_url: The URL for the slice's OpenFlow controller specified as <transport>:<hostname>[:<port>], where: - tranport is 'tcp' ('ssl' will be added later) - hostname is the controller's hostname - port is the port on which the controller listens to openflow messages (defaults to 6633). @type controller_url: string @param owner_email: email of the person responsible for the slice @type owner_email: string @param owner_password: initial password the user can use to login to the FlowVisor Web interface. Will need to be changed on initial login. @type owner_password: string @param switch_slivers: description of the topology and flowspace for slice @type switch_slivers: list of dicts @param options: will contain additional useful information for the operation @type options: dict @param kwargs: will contain additional useful information about the request. Of most use are the items in the C{kwargs['request'].META} dict. These include 'REMOTE_USER' which is the username of the user connecting or if using x509 certs then the domain name. Additionally, kwargs has the user using the 'user' key. @return: switches and links that have caused errors @rtype: dict ''' print "create_slice got the following:" print " slice_id: %s" % slice_id print " project_name: %s" % project_name print " project_desc: %s" % project_description print " slice_name: %s" % slice_name print " slice_desc: %s" % slice_description print " controller: %s" % controller_url print " owner_email: %s" % owner_email print " owner_pass: %s" % owner_password print " switch_slivers" pprint(switch_slivers, indent=8) print " options: " pprint(options, indent=8) # print " kwargs: " # pprint(kwargs, indent=8) # Determine slice style naming: legacy (Opt-in <= 0.7) or newer (FlowVisor >= 1.0) is_legacy_slice = True remotely_created = False # Retrieve information for current Experiment first try: # Legacy slices with older slice naming (Opt-in <= 0.7) e = Experiment.objects.filter(slice_id=options["legacy_slice_id"]) if not e: raise Exception except: # New slice naming style (for FlowVisor >= 1.0) -> No legacy slice try: uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False except: remotely_created = True is_legacy_slice = True e = Experiment.objects.filter(slice_id=slice_id) # If Experiment already existing => this is an update if (e.count() > 0): old_e = e[0] # Legacy slices: use combination of name and ID if is_legacy_slice: old_fv_name = old_e.get_fv_slice_name() # Otherwise, use UUID else: old_fv_name = old_e.slice_id update_exp = True old_exp_fs = ExperimentFLowSpace.objects.filter(exp=old_e) else: update_exp = False e = Experiment() e.slice_id = slice_id e.project_name = project_name e.project_desc = project_description e.slice_name = slice_name e.slice_desc = slice_description e.controller_url = controller_url e.owner_email = owner_email e.owner_password = owner_password e.save() all_efs = [] for sliver in switch_slivers: if "datapath_id" in sliver: dpid = sliver['datapath_id'] else: dpid = "00:" * 8 dpid = dpid[:-1] if len(sliver['flowspace']) == 0: # HACK: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid efs.direction = 2 all_efs.append(efs) else: for sfs in sliver['flowspace']: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid if "direction" in sfs: efs.direction = get_direction(sfs['direction']) else: efs.direction = 2 fs = convert_star(sfs) for attr_name,(to_str, from_str, width, om_name, of_name) in \ om_ch_translate.attr_funcs.items(): ch_start = "%s_start" % (attr_name) ch_end = "%s_end" % (attr_name) om_start = "%s_s" % (om_name) om_end = "%s_e" % (om_name) setattr(efs, om_start, from_str(fs[ch_start])) setattr(efs, om_end, from_str(fs[ch_end])) all_efs.append(efs) fv = FVServerProxy.objects.all()[0] if (update_exp): # Delete previous experiment from FV try: fv_success = fv.proxy.api.deleteSlice(old_fv_name) old_exp_fs.delete() old_e.delete() except Exception, exc: import traceback traceback.print_exc() if "slice does not exist" in str(exc): fv_success = True old_exp_fs.delete() old_e.delete() else: e.delete() print exc raise Exception( parseFVexception( exc, "While trying to update experiment, FV raised exception on the delete previous experiment step: " )) if (not fv_success): e.delete() raise Exception( "While trying to update experiment, FV returned False on the delete previous experiment step" )
"%s" % controller_url, "%s" % owner_email, ) for fs in all_efs: fs.save() print "Created slice with %s %s %s %s" % (new_fv_name, owner_password, controller_url, owner_email) except Exception, exc: import traceback traceback.print_exc() e.delete() print exc if (update_exp): raise Exception( parseFVexception( exc, "Could not create slice at the Flowvisor, after deleting old slice. Error was: " )) else: raise Exception( parseFVexception( exc, "Could not create slice at the Flowvisor. Error was: ")) if not fv_success: e.delete() if (update_exp): raise Exception( "Could not create slice at the Flowvisor, after deleting old slice. FV Returned False in createSlice call" ) else: raise Exception(
def CreateOFSliver(slice_urn,project_name,project_description,slice_name,slice_description,controller_url,owner_email,owner_password,switch_slivers,**kwargs): #slice_id = Experiment.objects.get(slice_urn=slice_urn).slice_id e = Experiment.objects.filter(slice_urn=slice_urn) if (e.count()>0): old_e = e[0] old_fv_name = old_e.slice_id update_exp = True old_exp_fs = ExperimentFLowSpace.objects.filter(exp=old_e) else: update_exp = False e = Experiment() slice_id = uuid.uuid4() e.slice_id = slice_id e.project_name = project_name e.project_desc = project_description e.slice_name = slice_name e.slice_desc = slice_description e.controller_url = controller_url e.owner_email = owner_email e.owner_password = owner_password e.slice_urn = slice_urn e.save() all_efs = [] for sliver in switch_slivers: if "datapath_id" in sliver: dpid = sliver['datapath_id'] else: dpid = "00:" * 8 dpid = dpid[:-1] if len(sliver['flowspace'])==0: # HACK: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid efs.direction = 2 all_efs.append(efs) else: for sfs in sliver['flowspace']: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid if "direction" in sfs: efs.direction = get_direction(sfs['direction']) else: efs.direction = 2 fs = convert_star(sfs) for attr_name,(to_str, from_str, width, om_name, of_name) in \ om_ch_translate.attr_funcs.items(): ch_start ="%s_start"%(attr_name) ch_end ="%s_end"%(attr_name) om_start ="%s_s"%(om_name) om_end ="%s_e"%(om_name) try: setattr(efs,om_start,from_str(fs[ch_start])) except: setattr(efs,om_start,from_str(int(fs[ch_start],16))) try: setattr(efs,om_end,from_str(fs[ch_end])) except: setattr(efs,om_end,from_str(int(fs[ch_end],16))) all_efs.append(efs) fv = FVServerProxy.objects.all()[0] if (update_exp): # delete previous experiment from FV try: fv_success = fv.proxy.api.deleteSlice(old_fv_name) old_exp_fs.delete() old_e.delete() except Exception, exc: import traceback traceback.print_exc() if "slice does not exist" in str(exc): fv_success = True old_exp_fs.delete() old_e.delete() else: e.delete() print exc raise Exception(parseFVexception(exc,"While trying to update experiment, FV raised exception on the delete previous experiment step: ")) if (not fv_success): e.delete() raise Exception("While trying to update experiment, FV returned False on the delete previous experiment step")
"%s" % slice_id, "%s" % owner_password, "%s" % controller_url, "%s" % owner_email, ) for fs in all_efs: fs.save() print "Created slice with %s %s %s %s" % ( slice_id, owner_password, controller_url, owner_email) except Exception,exc: import traceback traceback.print_exc() e.delete() print exc if (update_exp): raise Exception(parseFVexception(exc,"Could not create slice at the Flowvisor, after deleting old slice. Error was: ")) else: raise Exception(parseFVexception(exc,"Could not create slice at the Flowvisor. Error was: ")) if not fv_success: e.delete() if (update_exp): raise Exception( "Could not create slice at the Flowvisor, after deleting old slice. FV Returned False in createSlice call") else: raise Exception( "Could not create slice at the Flowvisor. FV Returned False in createSlice call") if (update_exp): from openflow.optin_manager.opts.helper import update_opts_into_exp [fv_args,match_list] = update_opts_into_exp(e)
for i in range(len(match_list)): match_list[i].fv_id = returned_ids[i] match_list[i].save() except Exception, exc: from openflow.optin_manager.opts.helper import opt_fses_outof_exp import traceback traceback.print_exc() all_opts = UserOpts.objects.filter(experiment=e) for opt in all_opts: optfses = OptsFlowSpace.objects.filter(opt=opt) opt_fses_outof_exp(optfses) all_opts.delete() print exc raise Exception( parseFVexception( exc, "Couldn't re-opt into updated experiment. Lost all the opt-ins: " )) try: # Get project detail URL to send via e-mail from openflow.optin_manager.opts import urls from django.core.urlresolvers import reverse project_detail_url = reverse("opt_in_experiment") or "/" # No "https://" check should be needed if settings are OK site_domain_url = "https://" + Site.objects.get_current( ).domain + project_detail_url # Tuple with the requested VLAN range try: vlan_range = "\nVLAN range: %s\n\n" % str( (all_efs[0].vlan_id_s, all_efs[0].vlan_id_e)) except:
"%s" % controller_url, "%s" % owner_email, ) for fs in all_efs: fs.save() print "Created slice with %s %s %s %s" % ( e.get_fv_slice_name(), owner_password, controller_url, owner_email) except Exception, exc: import traceback traceback.print_exc() e.delete() print exc if (update_exp): raise Exception( "Could not create slice at the Flowvisor, after deleting old slice. Error was: %s" % parseFVexception(exc)) else: raise Exception( "Could not create slice at the Flowvisor. Error was: %s" % parseFVexception(exc)) if not fv_success: e.delete() if (update_exp): raise Exception( "Could not create slice at the Flowvisor, after deleting old slice. FV Returned False in createSlice call" ) else: raise Exception( "Could not create slice at the Flowvisor. FV Returned False in createSlice call" )
def get_granted_flowspace(slice_id, **kwargs): ''' Return FlowVisor Rules for the slice. ''' def parse_granted_flowspaces(gfs): gfs_list=[] for fs in gfs: fs_dict = dict( flowspace=dict(), openflow=dict() ) fs_dict['openflow']=[] fs_dict['flowspace']=dict( mac_src_s=int_to_mac(fs.mac_src_s), mac_src_e=int_to_mac(fs.mac_src_e), mac_dst_s=int_to_mac(fs.mac_dst_s), mac_dst_e=int_to_mac(fs.mac_dst_e), eth_type_s=fs.eth_type_s, eth_type_e=fs.eth_type_e, vlan_id_s=fs.vlan_id_s, vlan_id_e=fs.vlan_id_e, ip_src_s=int_to_dotted_ip(fs.ip_src_s), ip_dst_s=int_to_dotted_ip(fs.ip_dst_s), ip_src_e=int_to_dotted_ip(fs.ip_src_e), ip_dst_e=int_to_dotted_ip(fs.ip_dst_e), ip_proto_s=fs.ip_proto_s, ip_proto_e=fs.ip_proto_e, tp_src_s=fs.tp_src_s, tp_dst_s=fs.tp_dst_s, tp_src_e=fs.tp_src_e, tp_dst_e=fs.tp_dst_e, ) openflow_dict=dict( dpid=fs.dpid, direction=fs.direction, port_number_s=fs.port_number_s, port_number_e=fs.port_number_e, ) existing_fs = False for prev_dict in gfs_list: if fs_dict['flowspace'] == prev_dict['flowspace']: if openflow_dict not in prev_dict['openflow']: prev_dict['openflow'].append(openflow_dict) existing_fs = True break if not existing_fs: fs_dict['openflow'].append(openflow_dict) gfs_list.append(fs_dict) return gfs_list try: #TODO: Check 100% that only with slice_id (domain+slice.id) is enough not to crash with some other clearinghouse connected to the optin exp = Experiment.objects.filter(slice_id = slice_id) gfs = [] if exp and len(exp) == 1: opts = exp[0].useropts_set.all() if opts: for opt in opts: gfs_temp = opt.optsflowspace_set.all() gfs.append(parse_granted_flowspaces(gfs_temp)) except Exception,e: import traceback traceback.print_exc() raise Exception(parseFVexception(e))
def create_slice(slice_id, project_name, project_description, slice_name, slice_description, controller_url, owner_email, owner_password, switch_slivers, options={}, **kwargs): ''' Create an OpenFlow slice. The C{switch_sliver} list contains a dict for each switch to be added to the slice's topology. Each such dict has the following items: - C{datapath_id}: the switch's datapath id - C{flowspace}: an array of dicts describing the switch's flowspace Each such dict has the following keys: - C{id}: integer. Per clearinghouse unique identifier for the rule. - C{port_num_start}, C{port_num_end}: string. the port range for this flowspace - C{dl_src_start}, C{dl_src_end}: string. link layer address range in "xx:xx:xx:xx:xx:xx" format or '*' for wildcard - C{dl_dst_start}, C{dl_dst_end}: string. link layer address range in "xx:xx:xx:xx:xx:xx" format or '*' for wildcard - C{vlan_id_start}, C{vlan_id_end}: string. vlan id range or "*" for wildcard - C{nw_src_start}, C{nw_src_end}: string. network address range in "x.x.x.x" format or '*' for wildcard - C{nw_dst_start}, C{nw_dst_end}: string. network address range in "x.x.x.x" format or '*' for wildcard - C{nw_proto_start}, C{nw_proto_end}: string. network protocol range or "*" for wildcard - C{tp_src_start}, C{tp_src_end}: string. transport port range or "*" for wildcard - C{tp_dst_start}, C{tp_dst_end}: string. transport port range or "*" for wildcard The call returns a dict with the following items: - C{error_msg}: a summary error message or "" if no errors occurred. - C{switches}: a list of dicts with the following items: - C{datapath_id}: id of the switch that caused the error - C{error}: optional error msg for the switch - all other fields of the C{switch_sliver} dicts mentioned above (port_num, direction, ...). The values for these items are the error messages associated with each field. @param slice_id: a string that uniquely identifies the slice at the clearinghouse. @type slice_id: int @param project_name: a name for the project under which this slice is created @type project_name: string @param project_description: text describing the project @type project_description: string @param slice_name: Name for the slice @type slice_name: string @param slice_description: text describing the slice/experiment @type slice_description: string @param controller_url: The URL for the slice's OpenFlow controller specified as <transport>:<hostname>[:<port>], where: - tranport is 'tcp' ('ssl' will be added later) - hostname is the controller's hostname - port is the port on which the controller listens to openflow messages (defaults to 6633). @type controller_url: string @param owner_email: email of the person responsible for the slice @type owner_email: string @param owner_password: initial password the user can use to login to the FlowVisor Web interface. Will need to be changed on initial login. @type owner_password: string @param switch_slivers: description of the topology and flowspace for slice @type switch_slivers: list of dicts @param options: will contain additional useful information for the operation @type options: dict @param kwargs: will contain additional useful information about the request. Of most use are the items in the C{kwargs['request'].META} dict. These include 'REMOTE_USER' which is the username of the user connecting or if using x509 certs then the domain name. Additionally, kwargs has the user using the 'user' key. @return: switches and links that have caused errors @rtype: dict ''' print "create_slice got the following:" print " slice_id: %s" % slice_id print " project_name: %s" % project_name print " project_desc: %s" % project_description print " slice_name: %s" % slice_name print " slice_desc: %s" % slice_description print " controller: %s" % controller_url print " owner_email: %s" % owner_email print " owner_pass: %s" % owner_password print " switch_slivers" pprint(switch_slivers, indent=8) print " options: " pprint(options, indent=8) # print " kwargs: " # pprint(kwargs, indent=8) # Determine slice style naming: legacy (Opt-in <= 0.7) or newer (FlowVisor >= 1.0) is_legacy_slice = True remotely_created = False # Retrieve information for current Experiment first try: # Legacy slices with older slice naming (Opt-in <= 0.7) e = Experiment.objects.filter(slice_id = options["legacy_slice_id"]) if not e: raise Exception except: # New slice naming style (for FlowVisor >= 1.0) -> No legacy slice try: uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False except: remotely_created = True is_legacy_slice = True e = Experiment.objects.filter(slice_id = slice_id) # If Experiment already existing => this is an update if (e.count()>0): old_e = e[0] # Legacy slices: use combination of name and ID if is_legacy_slice: old_fv_name = old_e.get_fv_slice_name() # Otherwise, use UUID else: old_fv_name = old_e.slice_id update_exp = True old_exp_fs = ExperimentFLowSpace.objects.filter(exp=old_e) else: update_exp = False e = Experiment() e.slice_id = slice_id e.project_name = project_name e.project_desc = project_description e.slice_name = slice_name e.slice_desc = slice_description e.controller_url = controller_url e.owner_email = owner_email e.owner_password = owner_password e.save() all_efs = [] for sliver in switch_slivers: if "datapath_id" in sliver: dpid = sliver['datapath_id'] else: dpid = "00:" * 8 dpid = dpid[:-1] if len(sliver['flowspace'])==0: # HACK: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid efs.direction = 2 all_efs.append(efs) else: for sfs in sliver['flowspace']: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid if "direction" in sfs: efs.direction = get_direction(sfs['direction']) else: efs.direction = 2 try: fs = convert_star(sfs) except Exception as exc: #The most probably cause is the fs was requested without VLANs e.delete() raise exc for attr_name,(to_str, from_str, width, om_name, of_name) in \ om_ch_translate.attr_funcs.items(): ch_start ="%s_start"%(attr_name) ch_end ="%s_end"%(attr_name) om_start ="%s_s"%(om_name) om_end ="%s_e"%(om_name) setattr(efs,om_start,from_str(fs[ch_start])) setattr(efs,om_end,from_str(fs[ch_end])) all_efs.append(efs) fv = FVServerProxy.objects.all()[0] if (update_exp): # Delete previous experiment from FV try: fv_success = fv.proxy.api.deleteSlice(old_fv_name) old_exp_fs.delete() old_e.delete() except Exception, exc: import traceback traceback.print_exc() if "slice does not exist" in str(exc): fv_success = True old_exp_fs.delete() old_e.delete() else: e.delete() print exc raise Exception(parseFVexception(exc,"While trying to update experiment, FV raised exception on the delete previous experiment step: ")) if (not fv_success): e.delete() raise Exception("While trying to update experiment, FV returned False on the delete previous experiment step")
class SliverUtils: @staticmethod def create_of_sliver(slice_urn, project_name, project_description, slice_name, slice_description, controller_url, owner_email, owner_password, switch_slivers, **kwargs): e = Experiment.objects.filter(slice_urn=slice_urn) if (e.count() > 0): old_e = e[0] old_fv_name = old_e.slice_id update_exp = True old_exp_fs = ExperimentFLowSpace.objects.filter(exp=old_e) else: update_exp = False e = Experiment() slice_id = uuid.uuid4() e.slice_id = slice_id e.project_name = project_name e.project_desc = project_description e.slice_name = slice_name e.slice_desc = slice_description e.controller_url = controller_url e.owner_email = owner_email e.owner_password = owner_password e.slice_urn = slice_urn e.save() all_efs = [] for sliver in switch_slivers: if "datapath_id" in sliver: dpid = sliver['datapath_id'] else: dpid = "00:" * 8 dpid = dpid[:-1] if len(sliver['flowspace']) == 0: # HACK: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid efs.direction = 2 all_efs.append(efs) else: for sfs in sliver['flowspace']: efs = ExperimentFLowSpace() efs.exp = e efs.dpid = dpid if "direction" in sfs: efs.direction = get_direction(sfs['direction']) else: efs.direction = 2 fs = convert_star(sfs) for attr_name,(to_str, from_str, width, om_name, of_name) in \ om_ch_translate.attr_funcs.items(): ch_start = "%s_start" % (attr_name) ch_end = "%s_end" % (attr_name) om_start = "%s_s" % (om_name) om_end = "%s_e" % (om_name) if not fs[ch_start]: continue if (ch_start or ch_end) in [ "nw_dst_start", "nw_dst_end", "nw_src_start", "nw_src_end" ]: fs[ch_start] = int_to_dotted_ip(fs[ch_start]) fs[ch_end] = int_to_dotted_ip(fs[ch_end]) try: setattr(efs, om_start, from_str(fs[ch_start])) except: setattr(efs, om_start, from_str(int(fs[ch_start], 16))) try: setattr(efs, om_end, from_str(fs[ch_end])) except: setattr(efs, om_end, from_str(int(fs[ch_end], 16))) all_efs.append(efs) fv = FVServerProxy.objects.all()[0] if (update_exp): # delete previous experiment from FV try: fv_success = fv.proxy.api.deleteSlice(old_fv_name) old_exp_fs.delete() old_e.delete() except Exception, exc: import traceback traceback.print_exc() if "slice does not exist" in str(exc): fv_success = True old_exp_fs.delete() old_e.delete() else: e.delete() print exc raise Exception( parseFVexception( exc, "While trying to update experiment, FV raised exception on the delete previous experiment step: " )) if (not fv_success): e.delete() raise Exception( "While trying to update experiment, FV returned False on the delete previous experiment step" ) # create the new experiment on FV try: fv_success = fv.proxy.api.createSlice( "%s" % slice_id, "%s" % owner_password, "%s" % controller_url, "%s" % owner_email, ) for fs in all_efs: fs.save() print "Created slice with %s %s %s %s" % ( slice_id, owner_password, controller_url, owner_email) except Exception, exc: import traceback traceback.print_exc() e.delete() print exc if (update_exp): raise Exception( parseFVexception( exc, "Could not create slice at the Flowvisor, after deleting old slice. Error was: " )) else: raise Exception( parseFVexception( exc, "Could not create slice at the Flowvisor. Error was: ") )
def get_granted_flowspace(slice_id, **kwargs): ''' Return FlowVisor Rules for the slice. ''' def parse_granted_flowspaces(gfs): gfs_list = [] for fs in gfs: fs_dict = dict(flowspace=dict(), openflow=dict()) fs_dict['openflow'] = [] fs_dict['flowspace'] = dict( mac_src_s=int_to_mac(fs.mac_src_s), mac_src_e=int_to_mac(fs.mac_src_e), mac_dst_s=int_to_mac(fs.mac_dst_s), mac_dst_e=int_to_mac(fs.mac_dst_e), eth_type_s=fs.eth_type_s, eth_type_e=fs.eth_type_e, vlan_id_s=fs.vlan_id_s, vlan_id_e=fs.vlan_id_e, ip_src_s=int_to_dotted_ip(fs.ip_src_s), ip_dst_s=int_to_dotted_ip(fs.ip_dst_s), ip_src_e=int_to_dotted_ip(fs.ip_src_e), ip_dst_e=int_to_dotted_ip(fs.ip_dst_e), ip_proto_s=fs.ip_proto_s, ip_proto_e=fs.ip_proto_e, tp_src_s=fs.tp_src_s, tp_dst_s=fs.tp_dst_s, tp_src_e=fs.tp_src_e, tp_dst_e=fs.tp_dst_e, ) openflow_dict = dict( dpid=fs.dpid, direction=fs.direction, port_number_s=fs.port_number_s, port_number_e=fs.port_number_e, ) existing_fs = False for prev_dict in gfs_list: if fs_dict['flowspace'] == prev_dict['flowspace']: if openflow_dict not in prev_dict['openflow']: prev_dict['openflow'].append(openflow_dict) existing_fs = True break if not existing_fs: fs_dict['openflow'].append(openflow_dict) gfs_list.append(fs_dict) return gfs_list try: #TODO: Check 100% that only with slice_id (domain+slice.id) is enough not to crash with some other clearinghouse connected to the optin exp = Experiment.objects.filter(slice_id=slice_id) gfs = [] if exp and len(exp) == 1: opts = exp[0].useropts_set.all() if opts: for opt in opts: gfs_temp = opt.optsflowspace_set.all() gfs.append(parse_granted_flowspaces(gfs_temp)) except Exception, e: import traceback traceback.print_exc() raise Exception(parseFVexception(e))
try: returned_ids = fv.proxy.api.changeFlowSpace(fv_args) for i in range(len(match_list)): match_list[i].fv_id = returned_ids[i] match_list[i].save() except Exception, exc: from openflow.optin_manager.opts.helper import opt_fses_outof_exp import traceback traceback.print_exc() all_opts = UserOpts.objects.filter(experiment=e) for opt in all_opts: optfses = OptsFlowSpace.objects.filter(opt = opt) opt_fses_outof_exp(optfses) all_opts.delete() print exc raise Exception(parseFVexception(exc,"Couldn't re-opt into updated experiment. Lost all the opt-ins: ")) try: # Get project detail URL to send via e-mail from openflow.optin_manager.opts import urls from django.core.urlresolvers import reverse project_detail_url = reverse("opt_in_experiment") or "/" # No "https://" check should be needed if settings are OK site_domain_url = "https://" + Site.objects.get_current().domain + project_detail_url # Tuple with the requested VLAN range try: vlan_range = "\nVLAN range: %s\n\n" % str((all_efs[0].vlan_id_s, all_efs[0].vlan_id_e)) except: vlan_range = "\n\n" send_mail(settings.EMAIL_SUBJECT_PREFIX+" Flowspace Request: OptinManager '"+str(project_name)+"'", "Hi, Island Manager\n\nA new flowspace was requested:\n\nProject: " + str(project_name) + "\nSlice: " + str(slice_name) + str(vlan_range) + "You may add a new Rule for this request at: %s" % site_domain_url, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=[settings.ROOT_EMAIL],) except Exception, e: