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")
Example #2
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

                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"
            )
Example #3
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")