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")
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" )
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")