def test_multi_fs_intersect(self): f1 = OptsFlowSpace(dpid="00:00:00:00:00:00:01",ip_src_s=10, ip_src_e=20,) f2 = OptsFlowSpace(dpid="00:00:00:00:00:00:01",port_number_s = 2, port_number_e=5, ip_src_s=10, ip_src_e=10,) f3 = OptsFlowSpace(dpid="00:00:00:00:00:00:02",ip_src_s=10, ip_src_e=20,) f4 = OptsFlowSpace(dpid="00:00:00:00:00:00:02",ip_dst_s=15, ip_dst_e=25,) fi = multi_fs_intersect([f1,f3], [f2,f4], OptsFlowSpace, True) self.assertNotEqual(fi,None) self.assertEqual(len(fi),2) if fi[0].dpid=="00:00:00:00:00:00:01": self.assertEqual(fi[0].port_number_s,2) self.assertEqual(fi[0].port_number_e,5) self.assertEqual(fi[0].ip_src_s,10) self.assertEqual(fi[0].ip_src_e,10) self.assertEqual(fi[1].ip_src_s,10) self.assertEqual(fi[1].ip_src_e,20) self.assertEqual(fi[1].ip_dst_s,15) self.assertEqual(fi[1].ip_dst_e,25) else: self.assertEqual(fi[1].port_number_s,2) self.assertEqual(fi[1].port_number_e,5) self.assertEqual(fi[1].ip_src_s,10) self.assertEqual(fi[1].ip_src_e,10) self.assertEqual(fi[0].ip_src_s,10) self.assertEqual(fi[0].ip_src_e,20) self.assertEqual(fi[0].ip_dst_s,15) self.assertEqual(fi[0].ip_dst_e,25)
def test_multi_fs_intersect(self): f1 = OptsFlowSpace( dpid="00:00:00:00:00:00:01", ip_src_s=10, ip_src_e=20, ) f2 = OptsFlowSpace( dpid="00:00:00:00:00:00:01", port_number_s=2, port_number_e=5, ip_src_s=10, ip_src_e=10, ) f3 = OptsFlowSpace( dpid="00:00:00:00:00:00:02", ip_src_s=10, ip_src_e=20, ) f4 = OptsFlowSpace( dpid="00:00:00:00:00:00:02", ip_dst_s=15, ip_dst_e=25, ) fi = multi_fs_intersect([f1, f3], [f2, f4], OptsFlowSpace, True) self.assertNotEqual(fi, None) self.assertEqual(len(fi), 2) if fi[0].dpid == "00:00:00:00:00:00:01": self.assertEqual(fi[0].port_number_s, 2) self.assertEqual(fi[0].port_number_e, 5) self.assertEqual(fi[0].ip_src_s, 10) self.assertEqual(fi[0].ip_src_e, 10) self.assertEqual(fi[1].ip_src_s, 10) self.assertEqual(fi[1].ip_src_e, 20) self.assertEqual(fi[1].ip_dst_s, 15) self.assertEqual(fi[1].ip_dst_e, 25) else: self.assertEqual(fi[1].port_number_s, 2) self.assertEqual(fi[1].port_number_e, 5) self.assertEqual(fi[1].ip_src_s, 10) self.assertEqual(fi[1].ip_src_e, 10) self.assertEqual(fi[0].ip_src_s, 10) self.assertEqual(fi[0].ip_src_e, 20) self.assertEqual(fi[0].ip_dst_s, 15) self.assertEqual(fi[0].ip_dst_e, 25)
def update_opts_into_exp(exp): ''' update all the opts into exp. The updated opt is the intersection of previous opt into the same experiment and the experiment's flowspace. Note that this ensures that experiments, by updating their flowspaces after a user optin into them, can not steal unwanted user flowspaces. @param exp: the experiment whose flowspace has changed and we need to update user opts into that experiment @type exp: Experiment object @return: [fv_args,match_list] flowvisor args to do the update. the fv_args should be passed to changeFlowSpace xmlrpc call in flowvisor. match list is the match entries for the first arguments in fv_args, so the returned ids from flowvisor should be saved back to them @type: [list, list] ''' useropts = UserOpts.objects.filter(experiment=exp) expFS = ExperimentFLowSpace.objects.filter(exp=exp) fv_args = [] match_list = [] # for each opted user into this experiemnt for useropt in useropts: #all the fses opted by this user into this experiemnt: optfses = OptsFlowSpace.objects.filter(opt=useropt) t_priority = useropt.priority t_nice = useropt.nice t_user = useropt.user updated_opt = multi_fs_intersect(expFS, optfses, OptsFlowSpace, True) opt_fses_outof_exp(optfses) useropt.delete() if len(updated_opt) > 0: [add_fv_args, new_match_list] = opt_fs_into_exp(updated_opt, exp, t_user, t_priority, t_nice) fv_args = add_fv_args + fv_args match_list = new_match_list + match_list return [fv_args, match_list]
def update_opts_into_exp(exp): ''' update all the opts into exp. The updated opt is the intersection of previous opt into the same experiment and the experiment's flowspace. Note that this ensures that experiments, by updating their flowspaces after a user optin into them, can not steal unwanted user flowspaces. @param exp: the experiment whose flowspace has changed and we need to update user opts into that experiment @type exp: Experiment object @return: [fv_args,match_list] flowvisor args to do the update. the fv_args should be passed to changeFlowSpace xmlrpc call in flowvisor. match list is the match entries for the first arguments in fv_args, so the returned ids from flowvisor should be saved back to them @type: [list, list] ''' useropts = UserOpts.objects.filter(experiment = exp) expFS = ExperimentFLowSpace.objects.filter(exp = exp) fv_args = [] match_list = [] # for each opted user into this experiemnt for useropt in useropts: #all the fses opted by this user into this experiemnt: optfses = OptsFlowSpace.objects.filter(opt = useropt) t_priority = useropt.priority t_nice = useropt.nice t_user = useropt.user updated_opt = multi_fs_intersect(expFS,optfses,OptsFlowSpace, True) opt_fses_outof_exp(optfses) useropt.delete() if len(updated_opt) > 0: [add_fv_args,new_match_list] = opt_fs_into_exp(updated_opt, exp, t_user, t_priority, t_nice) fv_args = add_fv_args + fv_args match_list = new_match_list + match_list return [fv_args,match_list]
def opt_fs_into_exp(optedFS, exp, user, priority, nice): ''' Opt the flowspace specified in optedFS into experiment exp @param optedFS: Flowpscae to be opted into experiment @type: Flowspace object @param exp: Experiment to be opted into @type exp: Experiemnt object @param user: user who is doing the opt-in @type user: User object @param priority: priority for this opt-in @type priority: integer @param nice: strict or nice optin @type nice: boolean @return: return the fv_args and the list of match structs created for this opt @type: [list,list] first list is fv_args, second one match_struct_list ''' expFS = ExperimentFLowSpace.objects.filter(exp=exp) intersected = False # add this opt to useropts tmp = UserOpts(experiment=exp, user=user, priority=priority, nice=nice) tmp.save() fv_args = [] match_list = [] for fs in expFS: opted = multi_fs_intersect([fs], optedFS, OptsFlowSpace) if (len(opted) > 0): intersected = True for opt in opted: opt.opt = tmp opt.dpid = fs.dpid opt.port_number_s = int(fs.port_number_s) opt.port_number_e = int(fs.port_number_e) opt.direction = fs.direction opt.save() #make Match struct matches = range_to_match_struct(opt) for single_match in matches: match = MatchStruct(match=single_match, priority=priority * Priority.Priority_Scale, fv_id=0, optfs=opt) match.save() match_list.append(match) #TODO 4 is hard coded fv_arg = { "operation": "ADD", "priority": "%d" % match.priority, "dpid": match.optfs.dpid, "match": match.match, "actions": "Slice=%s:4" % match.optfs.opt.experiment.get_fv_slice_name() } fv_args.append(fv_arg) # If there is any intersection, add them to FV if (not intersected): tmp.delete() return [fv_args, match_list]
def opt_fs_into_exp(optedFS, exp, user, priority, nice): ''' Opt the flowspace specified in optedFS into experiment exp @param optedFS: Flowpscae to be opted into experiment @type: Flowspace object @param exp: Experiment to be opted into @type exp: Experiemnt object @param user: user who is doing the opt-in @type user: User object @param priority: priority for this opt-in @type priority: integer @param nice: strict or nice optin @type nice: boolean @return: return the fv_args and the list of match structs created for this opt @type: [list,list] first list is fv_args, second one match_struct_list ''' expFS = ExperimentFLowSpace.objects.filter(exp = exp) # Slice ID defaults to its UUID, but let us check first the... slice_id = exp.slice_id # Backwards compatibility: check if slice_id follows the legacy style (= not UUID) try: import uuid uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False except Exception as e: is_legacy_slice = True # If legacy, get the older way to name it if is_legacy_slice: slice_id = exp.get_fv_slice_name() intersected = False # add this opt to useropts tmp = UserOpts(experiment=exp, user=user, priority=priority, nice=nice ) tmp.save() fv_args = [] match_list = [] some_exception = False opted = [] try: for fs in expFS: # XXX: lbergesio - This line is to force intersection # between the requested fs by the user and the one granted by the IM which is already the # the intesection between the adminFS (normally ALL) and the granted by the IM in the web form. # Most of the times VLAN requested != to the one granted so the fs is not granted nor pushed # to FV. # This is due to the original goal of optin and since OFELIA uses it in a different way, this # must never happen. So one solution is to replace the VLANS requested by user with the ones # granted by the IM. for optedfs in optedFS: #fs.vlan_id_e = optedfs.vlan_id_e #fs.vlan_id_s = optedfs.vlan_id_s if fs.vlan_id_e == optedfs.vlan_id_e and fs.vlan_id_s == optedfs.vlan_id_s: opted = multi_fs_intersect([fs],[optedfs],OptsFlowSpace) if (len(opted) > 0): intersected = True for opt in opted: opt.opt = tmp opt.dpid = fs.dpid opt.port_number_s = int(fs.port_number_s) opt.port_number_e = int(fs.port_number_e) opt.direction = fs.direction opt.save() #make Match struct matches = range_to_match_struct(opt) for single_match in matches: match = MatchStruct(match = single_match, priority = priority*Priority.Priority_Scale, fv_id=0, optfs=opt) match.save() match_list.append(match) #TODO 4 is hard coded fv_arg = {"operation":"ADD", "priority":"%d"%match.priority, "dpid":match.optfs.dpid,"match":match.match, # "actions":"Slice=%s:4"%match.optfs.opt.experiment.get_fv_slice_name()} "actions":"Slice=%s:4" % slice_id} fv_args.append(fv_arg) # If there is any intersection, add them to FV except Exception as e: # If some exception was raised, delete the tmp object and raise another exception tmp.delete() some_exception = str(e) raise Exception(some_exception) if (not intersected): print "WARNING!!! User FS request and IM granted FS do not match and no FS is being pushed to FV" tmp.delete() return [fv_args,match_list]
def opt_fs_into_exp(optedFS, exp, user, priority, nice): ''' Opt the flowspace specified in optedFS into experiment exp @param optedFS: Flowpscae to be opted into experiment @type: Flowspace object @param exp: Experiment to be opted into @type exp: Experiemnt object @param user: user who is doing the opt-in @type user: User object @param priority: priority for this opt-in @type priority: integer @param nice: strict or nice optin @type nice: boolean @return: return the fv_args and the list of match structs created for this opt @type: [list,list] first list is fv_args, second one match_struct_list ''' expFS = ExperimentFLowSpace.objects.filter(exp=exp) # Slice ID defaults to its UUID, but let us check first the... slice_id = exp.slice_id # Backwards compatibility: check if slice_id follows the legacy style (= not UUID) try: import uuid uuid.UUID('{%s}' % str(slice_id)) is_legacy_slice = False except Exception as e: is_legacy_slice = True # If legacy, get the older way to name it if is_legacy_slice: slice_id = exp.get_fv_slice_name() intersected = False # add this opt to useropts tmp = UserOpts(experiment=exp, user=user, priority=priority, nice=nice) tmp.save() fv_args = [] match_list = [] some_exception = False opted = [] try: for fs in expFS: # XXX: lbergesio - This line is to force intersection # between the requested fs by the user and the one granted by the IM which is already the # the intesection between the adminFS (normally ALL) and the granted by the IM in the web form. # Most of the times VLAN requested != to the one granted so the fs is not granted nor pushed # to FV. # This is due to the original goal of optin and since OFELIA uses it in a different way, this # must never happen. So one solution is to replace the VLANS requested by user with the ones # granted by the IM. for optedfs in optedFS: #fs.vlan_id_e = optedfs.vlan_id_e #fs.vlan_id_s = optedfs.vlan_id_s if fs.vlan_id_e == optedfs.vlan_id_e and fs.vlan_id_s == optedfs.vlan_id_s: opted = multi_fs_intersect([fs], [optedfs], OptsFlowSpace) if (len(opted) > 0): intersected = True for opt in opted: opt.opt = tmp opt.dpid = fs.dpid opt.port_number_s = int(fs.port_number_s) opt.port_number_e = int(fs.port_number_e) opt.direction = fs.direction opt.save() #make Match struct matches = range_to_match_struct(opt) for single_match in matches: match = MatchStruct(match=single_match, priority=priority * Priority.Priority_Scale, fv_id=0, optfs=opt) match.save() match_list.append(match) #TODO 4 is hard coded fv_arg = { "operation": "ADD", "priority": "%d" % match.priority, "dpid": match.optfs.dpid, "match": match.match, # "actions":"Slice=%s:4"%match.optfs.opt.experiment.get_fv_slice_name()} "actions": "Slice=%s:4" % slice_id } fv_args.append(fv_arg) # If there is any intersection, add them to FV except Exception as e: # If some exception was raised, delete the tmp object and raise another exception tmp.delete() some_exception = str(e) raise Exception(some_exception) if (not intersected): print "WARNING!!! User FS request and IM granted FS do not match and no FS is being pushed to FV" tmp.delete() return [fv_args, match_list]