Exemple #1
0
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)
Exemple #3
0
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)
Exemple #4
0
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))
Exemple #6
0
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")
Exemple #11
0
            "%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)
Exemple #12
0
                    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:
Exemple #13
0
            "%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"
            )
Exemple #14
0
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))
Exemple #15
0
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")
Exemple #16
0
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: ")
                )
Exemple #17
0
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))
Exemple #18
0
         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: