def Shutdown(slice_urn, user): slice = get_slice(slice_urn) tl = threadlocals.get_thread_locals() tl["project"] = slice.project tl["slice"] = slice slice.stop(user) return True
def test_obj_method_decorators(self): """ Tests that the L{require_obj_permissions} and L{require_obj_permissions_for_user} are correct. """ threadlocals.push_frame() d = threadlocals.get_thread_locals() for obj in self.objs: d["user_kw"] = self.u1 self.assertEqual(obj.get_val_x2(), 2) d["user_kw"] = self.u2 self.assertEqual(obj.get_val_x3_other_val(), 3) d["test_kw"] = self.o3 self.assertEqual(obj.get_val_x4(), 4) d["user_kw"] = self.u1 self.assertEqual(obj.get_val_x5_username(), 5) for obj in self.objs: d["user_kw"] = self.u2 self.assertRaises(PermissionDenied, obj.get_val_x2, obj) d["user_kw"] = self.o3 if obj != self.o3: self.assertRaises(PermissionDenied, obj.get_val_x3_other_val) d["test_kw"] = self.objs[1] if obj != self.objs[1]: self.assertRaises(PermissionDenied, obj.get_val_x4) d["user_kw"] = self.u2 self.assertRaises(PermissionDenied, obj.get_val_x5_username, obj)
def _create_sliver(self, slice): """ Corresponds to the CreateSliver call of the GENI aggregate API. Creates a sliver on the aggregate from this slice. """ logger.debug("Called GENIAggregate._create_sliver") user = threadlocals.get_thread_locals()["user"] rspec = self.as_leaf_class()._to_rspec(slice) info = GENISliceInfo.objects.get(slice=slice) slice_cred = self.get_slice_cred(slice, user) proxy = self.get_user_client(user) try: _ = proxy.CreateSliver( info.slice_urn, [slice_cred], rspec, [dict(name=settings.GCF_BASE_NAME, urn=get_ch_urn(), keys=[info.ssh_public_key]) ] ) except Exception as e: logger.error(traceback.format_exc()) raise Exception("Error creating sliver: %s" % e)
def __init__(self, *args, **kwargs): self.obj_permissions = kwargs.pop( "obj_permissions", ObjectPermission.objects.get_empty_query_set()) self.user = kwargs.pop( "user", threadlocals.get_thread_locals()["user"]) super(ProjectRoleForm, self).__init__(*args, **kwargs) self.fields["obj_permissions"].queryset = self.obj_permissions
def __init__(self, *args, **kwargs): self.obj_permissions = kwargs.pop( "obj_permissions", ObjectPermission.objects.get_empty_query_set()) self.user = kwargs.pop("user", threadlocals.get_thread_locals()["user"]) super(ProjectRoleForm, self).__init__(*args, **kwargs) self.fields["obj_permissions"].queryset = self.obj_permissions
def stop_slice(self, slice): super(SSHAggregate, self).start_slice(slice) user = threadlocals.get_thread_locals()["user"] for sliver in SSHServerSliver.objects.filter(slice=slice): server = sliver.resource.as_leaf_class() try: self.del_user(server, user.username) except: pass
def DeleteSliver(slice_urn, user): slice = get_slice(slice_urn) project = slice.project tl = threadlocals.get_thread_locals() tl["project"] = project tl["slice"] = slice slice.stop(user) slice.delete() # delete the project if there are no more slices in it if Slice.objects.filter(project=project).count() == 0: project.delete() return True
def test_delegation(self): """ Tests that permission delegation works correctly. """ threadlocals.push_frame() d = threadlocals.get_thread_locals() d["user_kw"] = self.u2 d["test_kw"] = self.u1 # Test allowed delegation self.assertRaises(PermissionDenied, self.objs[0].get_val_x2, self.objs[0]) self.assertRaises(PermissionDenied, self.objs[1].get_val_x2, self.objs[1]) give_permission_to("can_get_x2", self.objs[0], self.u2, giver=self.u1, can_delegate=True) self.assertEqual(self.objs[0].get_val_x2(), 2) self.assertRaises(PermissionDenied, self.objs[1].get_val_x2, self.objs[1]) give_permission_to("can_get_x2", self.objs[1], self.u2, giver=self.u1, can_delegate=False) self.assertEqual(self.objs[1].get_val_x2(), 2) # Test disallowed delegation self.assertRaises(PermissionCannotBeDelegated, give_permission_to, "can_get_x3", self.objs[0], self.u1, giver=self.u2, can_delegate=False) d["user_kw"] = self.u1 self.assertRaises(PermissionDenied, self.objs[0].get_val_x3_other_val, self.objs[0]) self.assertRaises(PermissionDenied, self.objs[1].get_val_x3_other_val, self.objs[1]) # Test cross delegation between types give_permission_to("can_get_x4", self.objs[0], self.u1, giver=self.o3, can_delegate=False) self.assertEqual(self.objs[0].get_val_x4(), 4) # Test delegation of delegated permission self.assertRaises(PermissionCannotBeDelegated, give_permission_to, "can_get_x4", self.objs[0], self.u2, giver=self.u1, can_delegate=False) give_permission_to("can_get_x2", self.objs[0], self.o3, giver=self.u2, can_delegate=True)
def setUp(self): """ Update settings, create DummyOMs and test models and login. """ # add the test application self.settings_manager.set( INSTALLED_APPS=settings.INSTALLED_APPS + [MOD + ".tests"], DEBUG_PROPAGATE_EXCEPTIONS=True, ) logger.debug("Updating RPC dispatchers.") rpc4django_views._register_rpcmethods( [MOD + ".tests"], restrict_introspection=False, dispatchers=rpc4django_views.dispatchers) self.su = User.objects.create_superuser( "superuser", "*****@*****.**", "password") self.client.login(username="******", password="******") om = DummyOM.objects.create() om.populate_links(5, 10) # Add the aggregate to the CH test_get_and_post_form( self.client, reverse("openflow_aggregate_create"), dict( name="DummyOM", description="DummyOM Description", location="Stanford, CA", usage_agreement="Do you agree?", username="******", password="******", url="test://testserver:80/dummyom/1/xmlrpc/", ) ) self.of = DummyOFAggregate.objects.create() # now get the list of resources and store it, then delete the # OpenFlowAggregate. self.of.snapshot_switches() OpenFlowAggregate.objects.all().delete() # set defaults for SSL_CLIENT_CERT and REMOTE_USER tl = threadlocals.get_thread_locals()
def setUp(self): """ Update settings, create DummyOMs and test models and login. """ # add the test application self.settings_manager.set( INSTALLED_APPS=settings.INSTALLED_APPS + [MOD + ".tests"], DEBUG_PROPAGATE_EXCEPTIONS=True, ) logger.debug("Updating RPC dispatchers.") rpc4django_views._register_rpcmethods( [MOD + ".tests"], restrict_introspection=False, dispatchers=rpc4django_views.dispatchers) self.su = User.objects.create_superuser("superuser", "*****@*****.**", "password") self.client.login(username="******", password="******") om = DummyOM.objects.create() om.populate_links(5, 10) # Add the aggregate to the CH test_get_and_post_form( self.client, reverse("openflow_aggregate_create"), dict( name="DummyOM", description="DummyOM Description", location="Stanford, CA", usage_agreement="Do you agree?", username="******", password="******", url="test://testserver:80/dummyom/1/xmlrpc/", )) self.of = DummyOFAggregate.objects.create() # now get the list of resources and store it, then delete the # OpenFlowAggregate. self.of.snapshot_switches() OpenFlowAggregate.objects.all().delete() # set defaults for SSL_CLIENT_CERT and REMOTE_USER tl = threadlocals.get_thread_locals()
def _delete_sliver(self, slice): """ Corresponds to the DeleteSliver call of the GENI aggregate API. Stop and delete slice at the aggregate. """ user = threadlocals.get_thread_locals()["user"] info = GENISliceInfo.objects.get(slice=slice) # Get the user's cert slice_cred = self.get_slice_cred(slice, user) proxy = self.get_user_client(user) try: ret = proxy.DeleteSliver(info.slice_urn, [slice_cred]) except Exception as e: logger.error(traceback.format_exc()) raise Exception("Error deleting sliver: %s" % e) return ret
def get_permittee_from_threadlocals(kw): """ Wrapper to get a permittee keyword from threadlocals and make sure it is usable. """ # Just skip if perm checks are disabled if not ExpedientPermission.objects.are_checks_enabled(): return None d = threadlocals.get_thread_locals() logger.debug("Got threadlocals %s" % d) try: permittee = d[kw] except KeyError: raise PermitteeNotInThreadLocals(kw) if not permittee: raise NonePermitteeException(kw) return permittee
def _delete_sliver(self, slice): """ Corresponds to the DeleteSliver call of the GENI aggregate API. Stop and delete slice at the aggregate. """ user = threadlocals.get_thread_locals()["user"] info = GENISliceInfo.objects.get(slice=slice) # Get the user's cert slice_cred = self.get_slice_cred(slice, user) proxy = self.get_user_client(user) try: ret = proxy.DeleteSliver( info.slice_urn, [slice_cred]) except Exception as e: logger.error(traceback.format_exc()) raise Exception("Error deleting sliver: %s" % e) return ret
def save(self, *args, **kwargs): """ Override the default save method to enforce permissions. """ pk = getattr(self, "pk", None) if not pk: # it's a new instance being created must_have_permission(permittee_kw, model_func(), create_perm) else: must_have_permission(permittee_kw, self, edit_perm) super(model_func(), self).save(*args, **kwargs) if not pk: # it was just created so give creator edit permissions d = threadlocals.get_thread_locals() give_permission_to( edit_perm, self, d[permittee_kw], can_delegate=True) give_permission_to( delete_perm, self, d[permittee_kw], can_delegate=True)
def post_message_to_current_user(msg_text, sender=None, msg_type=DatedMessage.TYPE_ANNOUNCE): """Post a message to the user whose request is being processed. This function depends on the threadlocals middleware to find the current user, so it must be installed. @param msg_text: The message to post for the user. @type msg_text: C{str} @keyword sender: The message sender. Defaults to None. @type sender: C{django.contrib.auth.models.User} @keyword msg_type: The type of the message. Defaults to L{DatedMessage.TYPE_ANNOUNCE}. @type msg_type: C{str} limited to one of L{DatedMessage}.TYPE_* """ user = threadlocals.get_thread_locals()["user"] DatedMessage.objects.post_message_to_user( msg_text, user, sender, msg_type)
def post_message_to_current_user(msg_text, sender=None, msg_type=DatedMessage.TYPE_ANNOUNCE): """Post a message to the user whose request is being processed. This function depends on the threadlocals middleware to find the current user, so it must be installed. @param msg_text: The message to post for the user. @type msg_text: C{str} @keyword sender: The message sender. Defaults to None. @type sender: C{django.contrib.auth.models.User} @keyword msg_type: The type of the message. Defaults to L{DatedMessage.TYPE_ANNOUNCE}. @type msg_type: C{str} limited to one of L{DatedMessage}.TYPE_* """ user = threadlocals.get_thread_locals()["user"] DatedMessage.objects.post_message_to_user(msg_text, user, sender, msg_type)
def _create_sliver(self, slice): """ Corresponds to the CreateSliver call of the GENI aggregate API. Creates a sliver on the aggregate from this slice. """ logger.debug("Called GENIAggregate._create_sliver") user = threadlocals.get_thread_locals()["user"] rspec = self.as_leaf_class()._to_rspec(slice) info = GENISliceInfo.objects.get(slice=slice) slice_cred = self.get_slice_cred(slice, user) proxy = self.get_user_client(user) try: _ = proxy.CreateSliver(info.slice_urn, [slice_cred], rspec, [ dict(name=settings.GCF_BASE_NAME, urn=get_ch_urn(), keys=[info.ssh_public_key]) ]) except Exception as e: logger.error(traceback.format_exc()) raise Exception("Error creating sliver: %s" % e)
def handle_noargs(self, **options): username = options.get("username") password = options.get("password") filename = options.get("filename") do_aggs = options.get("load_aggs") do_slices = options.get("load_slices") start_slices = options.get("start_slices") append = options.get("append") f = open(filename) data = load(f) f.close() client = Client() client.login(username=username, password=password) user = User.objects.get(username=username) threadlocals.get_thread_locals()["user"] = user if do_aggs: for agg_dict in data["aggregates"]: resp = test_get_and_post_form( client, reverse("openflow_aggregate_create"), agg_dict, ) assert (resp.status_code == 302) assert (re.search(r"/openflow/aggregate/\d+/links/$", resp["Location"])) if do_slices: for project_dict in data["projects"]: project, _ = Project.objects.get_or_create( name=project_dict["name"], description=project_dict["description"], ) create_project_roles(project, user) threadlocals.get_thread_locals()["project"] = project # add aggregates to project for aggregate in OpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) for aggregate in GCFOpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) # add slices to project for slice_dict in project_dict["slices"]: slice = Slice.objects.create( name=slice_dict["name"], description=slice_dict["description"], project=project, owner=user, ) OpenFlowSliceInfo.objects.create( slice=slice, controller_url=slice_dict["controller_url"], password=slice_dict["password"], ) info, _ = GENISliceInfo.objects.get_or_create( slice=slice, ) if not info.ssh_private_key or not info.ssh_public_key: info.generate_ssh_keys() info.save() # add aggregates to slices for aggregate in OpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, slice) for aggregate in GCFOpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, slice) # add slivers slivers = [] for dpid, port in slice_dict["ifaces"]: try: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=OpenFlowInterface.objects.get( port_num=port, switch__datapath_id=dpid), ) slivers.append(sliver) except OpenFlowInterface.DoesNotExist: continue # add flowspace for sfs_dict in slice_dict["sfs"]: fs_dict = {} for attr in "dl_src", "dl_dst", "dl_type", "vlan_id", \ "nw_src", "nw_dst", "nw_proto", "tp_dst", "tp_src": fs_dict[attr + "_start"] = sfs_dict[attr] fs_dict[attr + "_end"] = sfs_dict[attr] fs = FlowSpaceRule.objects.create(**fs_dict) for sliver in slivers: fs.slivers.add(sliver) if start_slices: tl = threadlocals.get_thread_locals() tl["project"] = project tl["slice"] = slice slice.start(user)
def test_gapi_CreateSliver( self, proj_name="test project", proj_desc="test project description", slice_name="test slice", slice_desc="test slice description", username="******", firstname="gapi", lastname="user", password="******", affiliation="Stanford", email="*****@*****.**", controller_url="tcp:bla.com:6633", fs1=dict( dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(4455, 4455), nw_src=("123.123.132.123", "222.222.222.222"), ), fs2=dict( dl_src=("11:22:33:44:55:66", "11:22:33:44:55:77"), dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(None, 4455), nw_src=("123.123.132.123", "222.222.222.222"), nw_proto=(4, 4), tp_src=(123, 123), ), slice=None, expiration=datetime.now() + timedelta(days=1), create_aggregates=True, ): # IMPORTANT: If you change fs1 and fs2, make sure that # the rspec for fs1 is shorter than that for fs2 since # the test needs to order them by length. # add the aggregates if create_aggregates: self.test_create_aggregates() self.client.logout() # setup threadlocals tl = threadlocals.get_thread_locals() tl["user"] = self.su # create the info user, _ = create_or_update(model=User, filter_attrs={"username": username}, new_attrs={ "first_name": firstname, "last_name": lastname, "email": email, }) create_or_update(UserProfile, filter_attrs={ "user": user, }, new_attrs={ "affiliation": affiliation, }) if slice: project = slice.project project.name = proj_name project.description = proj_desc project.save() else: project, _ = create_or_update( Project, filter_attrs=dict(name=proj_name), new_attrs=dict(description=proj_desc), ) if not slice: slice = Slice.objects.create( project=project, name=slice_name, description=slice_desc, owner=user, expiration_date=expiration, ) # select ports and switches random.seed(0) fs1_switches = random.sample(list(OpenFlowSwitch.objects.all()), 10) fs1_ports = random.sample(list(OpenFlowInterface.objects.all()), 10) fs2_switches = random.sample(list(OpenFlowSwitch.objects.all()), 10) fs2_ports = random.sample(list(OpenFlowInterface.objects.all()), 10) if slice: OpenFlowInterfaceSliver.objects.filter(slice=slice).delete() FlowSpaceRule.objects.filter(slivers__slice=slice).delete() def create_port_slivers(fs, ports): slivers = [] for p in ports: slivers.append( OpenFlowInterfaceSliver.objects.create(slice=slice, resource=p)) kw = {} for k, r in fs.items(): if r[0]: kw[k + "_start"] = r[0] if r[1]: kw[k + "_end"] = r[1] rule = FlowSpaceRule.objects.create(**kw) for s in slivers: rule.slivers.add(s) return rule # create the slivers for the slice r1 = create_port_slivers(fs1, fs1_ports) r2 = create_port_slivers(fs2, fs2_ports) create_or_update( OpenFlowSliceInfo, filter_attrs=dict(slice=slice), new_attrs=dict(password=password, controller_url=controller_url), ) # get the rspec using only the ports resv_rspec = rspec_mod.create_resv_rspec(user, slice) # add the full switches to the reservation rspec root = et.fromstring(resv_rspec) fs_elems = root.findall(".//%s" % rspec_mod.FLOWSPACE_TAG) def add_switches(elem, switches): for s in switches: et.SubElement( elem, rspec_mod.SWITCH_TAG, { rspec_mod.URN: rspec_mod._dpid_to_urn(s.datapath_id), }, ) add_switches(fs_elems[0], fs1_switches) add_switches(fs_elems[1], fs2_switches) resv_rspec = et.tostring(root) # Now add the switches into the slice and get the expected rspec # that will be returned def add_switch_slivers(rule, switches): for s in switches: ports = OpenFlowInterface.objects.filter(switch=s) for p in ports: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=p) rule.slivers.add(sliver) add_switch_slivers(r1, fs1_switches) add_switch_slivers(r2, fs2_switches) expected_resv_rspec = rspec_mod.create_resv_rspec(user, slice) # delete created state project.delete() user.delete() r1.delete() r2.delete() # create the slice using gapi ret_rspec = self.rpc.CreateSliver( self.slice_gid.get_urn(), [self.slice_cred], resv_rspec, {}, ) ret = order_rspec(ret_rspec) exp = order_rspec(expected_resv_rspec) self.assertEqual( ret, exp, "Expected:\n%s \nFound:\n%s" % (exp, ret), ) # check that the created state is what is expected self.assertEqual(GENISliceInfo.objects.all()[0].slice_urn, self.slice_gid.get_urn()) project = Project.objects.all()[0] self.assertEqual(project.name, proj_name) self.assertEqual(project.description, proj_desc) slice = Slice.objects.all()[0] self.assertEqual(slice.name, slice_name) self.assertEqual(slice.description, slice_desc) self.assertEqual(slice.project, project) self.assertEqual( long(time.mktime(slice.expiration_date.timetuple())), long(time.mktime(expiration.timetuple())), ) user = User.objects.get(username=username) self.assertEqual(user.first_name, firstname) self.assertEqual(user.last_name, lastname) self.assertEqual(user.email, email) user_profile = UserProfile.objects.all()[0] self.assertEqual(user_profile.affiliation, affiliation) self.assertEqual(user, user) r1 = FlowSpaceRule.objects.all()[0] r2 = FlowSpaceRule.objects.all()[1] def verif_rule(r, fs): for field in "dl_src", "dl_dst", "dl_type", \ "vlan_id", "nw_src", "nw_dst", "nw_proto", \ "tp_src", "tp_dst": if field in fs: self.assertEqual(fs[field][0], getattr(r, field + "_start")) self.assertEqual(fs[field][1], getattr(r, field + "_end")) else: self.assertEqual(None, getattr(r, field + "_start")) self.assertEqual(None, getattr(r, field + "_end")) verif_rule(r1, fs1) verif_rule(r2, fs2) # check the slivers in rules: make sure each rule has all the # the interfaces it is supposed to have. def verif_slivers(r, ports, switches): all_ports = [] all_ports.extend(ports) for s in switches: all_ports.extend(OpenFlowInterface.objects.filter(switch=s)) all_ports = set(all_ports) # check number of interfaces self.assertEqual(len(all_ports), r.slivers.count()) # check slivers for sliver in r.slivers.all(): self.assertTrue(sliver.resource.as_leaf_class() in all_ports) verif_slivers(r1, fs1_ports, fs1_switches) verif_slivers(r2, fs2_ports, fs2_switches) return ret_rspec
def CreateSliver(slice_urn, rspec, user): (project_name, project_desc, slice_name, slice_desc, slice_expiry, controller_url, firstname, lastname, affiliation, email, password, slivers) = rspec_mod.parse_slice(rspec) logger.debug("Parsed Rspec") slice_expiry = datetime.fromtimestamp(slice_expiry) give_permission_to("can_create_project", Project, user) user.first_name = firstname user.last_name = lastname user.email = email profile = UserProfile.get_or_create_profile(user) profile.affiliation = affiliation user.save() profile.save() # Check if the slice exists try: slice = get_slice(slice_urn) # update the slice info slice.description = slice_desc slice.name = slice_name slice.expiration_date = slice_expiry slice.save() # update the project info slice.project.name = project_name slice.project.description = project_desc slice.project.save() project = slice.project except Slice.DoesNotExist: # Check if the project exists try: project = Project.objects.get(name=project_name) # update the project info logger.debug("Updating project") project.description = project_desc project.save() except Project.DoesNotExist: # create the project logger.debug("Creating project") project = Project.objects.create( name=project_name, description=project_desc, ) create_project_roles(project, user) # create the slice logger.debug("Creating slice") try: slice = Slice.objects.create( name=slice_name, description=slice_desc, project=project, owner=user, expiration_date = slice_expiry, ) except IntegrityError: raise DuplicateSliceNameException(slice_name) logger.debug("Creating/updating slice info") # create openflow slice info for the slice create_or_update( OpenFlowSliceInfo, filter_attrs={"slice": slice}, new_attrs={ "controller_url": controller_url, "password": password, }, ) logger.debug("creating gapislice") # store a pointer to this slice using the slice_urn create_or_update( GENISliceInfo, filter_attrs={ "slice": slice, }, new_attrs={ "slice_urn": slice_urn, }, ) logger.debug("adding resources") sliver_ids = [] # delete all flowspace in the slice FlowSpaceRule.objects.filter(slivers__slice=slice).delete() # add the new flowspace for fs_dict, iface_qs in slivers: # give the user, project, slice permission to use the aggregate aggregate_ids = list(iface_qs.values_list("aggregate", flat=True)) for agg_id in aggregate_ids: aggregate = Aggregate.objects.get(id=agg_id).as_leaf_class() give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) give_permission_to("can_use_aggregate", aggregate, slice) # Create flowspace logger.debug("Creating flowspace %s" % fs_dict) fs = FlowSpaceRule.objects.create(**fs_dict) # make sure all the selected interfaces are added for iface in iface_qs: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=iface) sliver_ids.append(sliver.id) fs.slivers.add(sliver) logger.debug("Deleting old resources") # Delete all removed interfaces OpenFlowInterfaceSliver.objects.exclude(id__in=sliver_ids).delete() logger.debug("Starting the slice %s %s" % (slice, slice.name)) # make the reservation tl = threadlocals.get_thread_locals() tl["project"] = project tl["slice"] = slice slice.start(user) logger.debug("Done creating sliver") return rspec_mod.create_resv_rspec(user, slice)
def CreateSliver(slice_urn, rspec, user): (project_name, project_desc, slice_name, slice_desc, slice_expiry, controller_url, firstname, lastname, affiliation, email, password, slivers) = rspec_mod.parse_slice(rspec) logger.debug("Parsed Rspec") slice_expiry = datetime.fromtimestamp(slice_expiry) give_permission_to("can_create_project", Project, user) user.first_name = firstname user.last_name = lastname user.email = email profile = UserProfile.get_or_create_profile(user) profile.affiliation = affiliation user.save() profile.save() # Check if the slice exists try: slice = get_slice(slice_urn) # update the slice info slice.description = slice_desc slice.name = slice_name slice.expiration_date = slice_expiry slice.save() # update the project info slice.project.name = project_name slice.project.description = project_desc slice.project.save() project = slice.project except Slice.DoesNotExist: # Check if the project exists try: project = Project.objects.get(name=project_name) # update the project info logger.debug("Updating project") project.description = project_desc project.save() except Project.DoesNotExist: # create the project logger.debug("Creating project") project = Project.objects.create( name=project_name, description=project_desc, ) create_project_roles(project, user) # create the slice logger.debug("Creating slice") try: slice = Slice.objects.create( name=slice_name, description=slice_desc, project=project, owner=user, expiration_date=slice_expiry, ) except IntegrityError: raise DuplicateSliceNameException(slice_name) logger.debug("Creating/updating slice info") # create openflow slice info for the slice create_or_update( OpenFlowSliceInfo, filter_attrs={"slice": slice}, new_attrs={ "controller_url": controller_url, "password": password, }, ) logger.debug("creating gapislice") # store a pointer to this slice using the slice_urn create_or_update( GENISliceInfo, filter_attrs={ "slice": slice, }, new_attrs={ "slice_urn": slice_urn, }, ) logger.debug("adding resources") sliver_ids = [] # delete all flowspace in the slice FlowSpaceRule.objects.filter(slivers__slice=slice).delete() # add the new flowspace for fs_dict, iface_qs in slivers: # give the user, project, slice permission to use the aggregate aggregate_ids = list(iface_qs.values_list("aggregate", flat=True)) for agg_id in aggregate_ids: aggregate = Aggregate.objects.get(id=agg_id).as_leaf_class() give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) give_permission_to("can_use_aggregate", aggregate, slice) # Create flowspace logger.debug("Creating flowspace %s" % fs_dict) fs = FlowSpaceRule.objects.create(**fs_dict) # make sure all the selected interfaces are added for iface in iface_qs: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=iface) sliver_ids.append(sliver.id) fs.slivers.add(sliver) logger.debug("Deleting old resources") # Delete all removed interfaces OpenFlowInterfaceSliver.objects.exclude(id__in=sliver_ids).delete() logger.debug("Starting the slice %s %s" % (slice, slice.name)) # make the reservation tl = threadlocals.get_thread_locals() tl["project"] = project tl["slice"] = slice slice.start(user) logger.debug("Done creating sliver") return rspec_mod.create_resv_rspec(user, slice)
def test_reserve_sliver(self): self.test_add_aggregate() proj_name = "test project" proj_desc = "test project description" slice_name = "test slice" slice_desc = "test slice description" username = "******" firstname = "gapi" lastname = "user" password = "******" affiliation = "Stanford" email = "*****@*****.**" controller_url = "tcp:bla.com:6633" fs1 = dict( dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(4455, 4455), nw_src=("123.123.132.123", "222.222.222.222"), ) fs2 = dict( dl_src=("11:22:33:44:55:66", "11:22:33:44:55:77"), dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(None, 4455), nw_src=("123.123.132.123", "222.222.222.222"), nw_proto=(4,4), tp_src=(123,123), ) agg = GCFOpenFlowAggregate.objects.all()[0] # setup threadlocals tl = threadlocals.get_thread_locals() tl["user"] = self.su project = Project.objects.create( name=proj_name, description=proj_desc, ) tl["project"] = project url = reverse("project_add_agg", args=[project.id]) response = self.client.post( path=url, data={"id": agg.id}, ) self.assertTrue(project.aggregates.count() == 1) self.assertRedirects( response, url, ) slice = Slice.objects.create( project=project, name=slice_name, description=slice_desc, owner=self.su, ) tl["slice"] = slice # To avoid expensive key creation info = GENISliceInfo.objects.get(slice=slice) info.ssh_private_key="abc" info.ssh_public_key = "def" info.save() slice_add_agg_url = reverse("slice_add_agg", args=[slice.id]) # add aggregate to slice gopenflow_aggregate_slice_add_url = reverse( "gopenflow_aggregate_slice_add", kwargs={ "agg_id": agg.id, "slice_id": slice.id, } ) # post the form to add aggregate to slice response = self.client.post( path=slice_add_agg_url, data={"id": agg.id}, ) # should go the openflow special add aggregates page self.assertRedirects( response, gopenflow_aggregate_slice_add_url + "?next=" + slice_add_agg_url, ) # Set the slice info response = test_get_and_post_form( self.client, gopenflow_aggregate_slice_add_url+ "?next=" + slice_add_agg_url, params=dict( controller_url="tcp:blabla:6633", password="******", ) ) self.assertRedirects( response, slice_add_agg_url, ) self.assertEqual( slice.aggregates.count(), 1, "Did not add aggregate to slice.") # select ports and switches random.seed(0) fs1_switches = random.sample(list(OpenFlowSwitch.objects.all()), 2) fs1_ports = random.sample(list(OpenFlowInterface.objects.all()), 2) fs2_switches = random.sample(list(OpenFlowSwitch.objects.all()), 2) fs2_ports = random.sample(list(OpenFlowInterface.objects.all()), 2) def create_port_slivers(fs, ports): slivers = [] for p in ports: slivers.append(OpenFlowInterfaceSliver.objects.create( slice=slice, resource=p)) kw = {} for k, r in fs.items(): if r[0]: kw[k+"_start"] = r[0] if r[1]: kw[k+"_end"] = r[1] rule = FlowSpaceRule.objects.create(**kw) for s in slivers: rule.slivers.add(s) return rule # create the slivers for the slice r1 = create_port_slivers(fs1, fs1_ports) r2 = create_port_slivers(fs2, fs2_ports) create_or_update(OpenFlowSliceInfo, filter_attrs=dict(slice=slice), new_attrs=dict(password=password, controller_url=controller_url), ) def add_switch_slivers(rule, switches): for s in switches: ports = OpenFlowInterface.objects.filter(switch=s) for p in ports: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=p) rule.slivers.add(sliver) add_switch_slivers(r1, fs1_switches) add_switch_slivers(r2, fs2_switches) # get the expected reservation rspec exp_rspec = create_resv_rspec(self.su, slice) slice.start(self.su) actual_rspec = DummyOFAggregate.objects.all()[0].resv_rspec self.assertEqual(exp_rspec, actual_rspec)
def test_reserve_sliver(self): self.test_add_aggregate() proj_name = "test project" proj_desc = "test project description" slice_name = "test slice" slice_desc = "test slice description" username = "******" firstname = "gapi" lastname = "user" password = "******" affiliation = "Stanford" email = "*****@*****.**" controller_url = "tcp:bla.com:6633" fs1 = dict( dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(4455, 4455), nw_src=("123.123.132.123", "222.222.222.222"), ) fs2 = dict( dl_src=("11:22:33:44:55:66", "11:22:33:44:55:77"), dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(None, 4455), nw_src=("123.123.132.123", "222.222.222.222"), nw_proto=(4, 4), tp_src=(123, 123), ) agg = GCFOpenFlowAggregate.objects.all()[0] # setup threadlocals tl = threadlocals.get_thread_locals() tl["user"] = self.su project = Project.objects.create( name=proj_name, description=proj_desc, ) tl["project"] = project url = reverse("project_add_agg", args=[project.id]) response = self.client.post( path=url, data={"id": agg.id}, ) self.assertTrue(project.aggregates.count() == 1) self.assertRedirects( response, url, ) slice = Slice.objects.create( project=project, name=slice_name, description=slice_desc, owner=self.su, ) tl["slice"] = slice # To avoid expensive key creation info = GENISliceInfo.objects.get(slice=slice) info.ssh_private_key = "abc" info.ssh_public_key = "def" info.save() slice_add_agg_url = reverse("slice_add_agg", args=[slice.id]) # add aggregate to slice gopenflow_aggregate_slice_add_url = reverse( "gopenflow_aggregate_slice_add", kwargs={ "agg_id": agg.id, "slice_id": slice.id, }) # post the form to add aggregate to slice response = self.client.post( path=slice_add_agg_url, data={"id": agg.id}, ) # should go the openflow special add aggregates page self.assertRedirects( response, gopenflow_aggregate_slice_add_url + "?next=" + slice_add_agg_url, ) # Set the slice info response = test_get_and_post_form(self.client, gopenflow_aggregate_slice_add_url + "?next=" + slice_add_agg_url, params=dict( controller_url="tcp:blabla:6633", password="******", )) self.assertRedirects( response, slice_add_agg_url, ) self.assertEqual(slice.aggregates.count(), 1, "Did not add aggregate to slice.") # select ports and switches random.seed(0) fs1_switches = random.sample(list(OpenFlowSwitch.objects.all()), 2) fs1_ports = random.sample(list(OpenFlowInterface.objects.all()), 2) fs2_switches = random.sample(list(OpenFlowSwitch.objects.all()), 2) fs2_ports = random.sample(list(OpenFlowInterface.objects.all()), 2) def create_port_slivers(fs, ports): slivers = [] for p in ports: slivers.append( OpenFlowInterfaceSliver.objects.create(slice=slice, resource=p)) kw = {} for k, r in fs.items(): if r[0]: kw[k + "_start"] = r[0] if r[1]: kw[k + "_end"] = r[1] rule = FlowSpaceRule.objects.create(**kw) for s in slivers: rule.slivers.add(s) return rule # create the slivers for the slice r1 = create_port_slivers(fs1, fs1_ports) r2 = create_port_slivers(fs2, fs2_ports) create_or_update( OpenFlowSliceInfo, filter_attrs=dict(slice=slice), new_attrs=dict(password=password, controller_url=controller_url), ) def add_switch_slivers(rule, switches): for s in switches: ports = OpenFlowInterface.objects.filter(switch=s) for p in ports: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=p) rule.slivers.add(sliver) add_switch_slivers(r1, fs1_switches) add_switch_slivers(r2, fs2_switches) # get the expected reservation rspec exp_rspec = create_resv_rspec(self.su, slice) slice.start(self.su) actual_rspec = DummyOFAggregate.objects.all()[0].resv_rspec self.assertEqual(exp_rspec, actual_rspec)
def _to_rspec(self, slice): """ See L{GENIAggregate._to_rspec}. """ user = threadlocals.get_thread_locals()["user"] return create_resv_rspec(user, slice, aggregate=self)
def handle_noargs(self, **options): username = options.get("username") password = options.get("password") filename = options.get("filename") do_aggs = options.get("load_aggs") do_slices = options.get("load_slices") start_slices = options.get("start_slices") append = options.get("append") f = open(filename) data = load(f) f.close() client = Client() client.login(username=username, password=password) user = User.objects.get(username=username) threadlocals.get_thread_locals()["user"] = user if do_aggs: for agg_dict in data["aggregates"]: resp = test_get_and_post_form( client, reverse("openflow_aggregate_create"), agg_dict, ) assert(resp.status_code == 302) assert( re.search( r"/openflow/aggregate/\d+/links/$", resp["Location"])) if do_slices: for project_dict in data["projects"]: project, _ = Project.objects.get_or_create( name=project_dict["name"], description=project_dict["description"], ) create_project_roles(project, user) threadlocals.get_thread_locals()["project"] = project # add aggregates to project for aggregate in OpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) for aggregate in GCFOpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, user) give_permission_to("can_use_aggregate", aggregate, project) # add slices to project for slice_dict in project_dict["slices"]: slice = Slice.objects.create( name=slice_dict["name"], description=slice_dict["description"], project=project, owner=user, ) OpenFlowSliceInfo.objects.create( slice=slice, controller_url=slice_dict["controller_url"], password=slice_dict["password"], ) info, _ = GENISliceInfo.objects.get_or_create( slice=slice, ) if not info.ssh_private_key or not info.ssh_public_key: info.generate_ssh_keys() info.save() # add aggregates to slices for aggregate in OpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, slice) for aggregate in GCFOpenFlowAggregate.objects.all(): give_permission_to("can_use_aggregate", aggregate, slice) # add slivers slivers = [] for dpid, port in slice_dict["ifaces"]: try: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=OpenFlowInterface.objects.get( port_num=port, switch__datapath_id=dpid), ) slivers.append(sliver) except OpenFlowInterface.DoesNotExist: continue # add flowspace for sfs_dict in slice_dict["sfs"]: fs_dict = {} for attr in "dl_src", "dl_dst", "dl_type", "vlan_id", \ "nw_src", "nw_dst", "nw_proto", "tp_dst", "tp_src": fs_dict[attr+"_start"] = sfs_dict[attr] fs_dict[attr+"_end"] = sfs_dict[attr] fs = FlowSpaceRule.objects.create(**fs_dict) for sliver in slivers: fs.slivers.add(sliver) if start_slices: tl = threadlocals.get_thread_locals() tl["project"] = project tl["slice"] = slice slice.start(user)
def test_gapi_CreateSliver(self, proj_name = "test project", proj_desc = "test project description", slice_name = "test slice", slice_desc = "test slice description", username = "******", firstname = "gapi", lastname = "user", password = "******", affiliation = "Stanford", email = "*****@*****.**", controller_url = "tcp:bla.com:6633", fs1 = dict( dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(4455, 4455), nw_src=("123.123.132.123", "222.222.222.222"), ), fs2 = dict( dl_src=("11:22:33:44:55:66", "11:22:33:44:55:77"), dl_dst=("11:22:33:44:55:66", None), dl_type=(1234, 1236), vlan_id=(None, 4455), nw_src=("123.123.132.123", "222.222.222.222"), nw_proto=(4,4), tp_src=(123,123), ), slice=None, expiration=datetime.now() + timedelta(days=1), create_aggregates=True, ): # IMPORTANT: If you change fs1 and fs2, make sure that # the rspec for fs1 is shorter than that for fs2 since # the test needs to order them by length. # add the aggregates if create_aggregates: self.test_create_aggregates() self.client.logout() # setup threadlocals tl = threadlocals.get_thread_locals() tl["user"] = self.su # create the info user, _ = create_or_update( model=User, filter_attrs={"username": username}, new_attrs={ "first_name": firstname, "last_name": lastname, "email": email, } ) create_or_update(UserProfile, filter_attrs={ "user": user, }, new_attrs={ "affiliation":affiliation, } ) if slice: project = slice.project project.name = proj_name project.description = proj_desc project.save() else: project, _ = create_or_update(Project, filter_attrs=dict(name=proj_name), new_attrs=dict(description=proj_desc), ) if not slice: slice = Slice.objects.create( project=project, name=slice_name, description=slice_desc, owner=user, expiration_date=expiration, ) # select ports and switches random.seed(0) fs1_switches = random.sample(list(OpenFlowSwitch.objects.all()), 10) fs1_ports = random.sample(list(OpenFlowInterface.objects.all()), 10) fs2_switches = random.sample(list(OpenFlowSwitch.objects.all()), 10) fs2_ports = random.sample(list(OpenFlowInterface.objects.all()), 10) if slice: OpenFlowInterfaceSliver.objects.filter( slice=slice).delete() FlowSpaceRule.objects.filter(slivers__slice=slice).delete() def create_port_slivers(fs, ports): slivers = [] for p in ports: slivers.append(OpenFlowInterfaceSliver.objects.create( slice=slice, resource=p)) kw = {} for k, r in fs.items(): if r[0]: kw[k+"_start"] = r[0] if r[1]: kw[k+"_end"] = r[1] rule = FlowSpaceRule.objects.create(**kw) for s in slivers: rule.slivers.add(s) return rule # create the slivers for the slice r1 = create_port_slivers(fs1, fs1_ports) r2 = create_port_slivers(fs2, fs2_ports) create_or_update(OpenFlowSliceInfo, filter_attrs=dict(slice=slice), new_attrs=dict(password=password, controller_url=controller_url), ) # get the rspec using only the ports resv_rspec = rspec_mod.create_resv_rspec(user, slice) # add the full switches to the reservation rspec root = et.fromstring(resv_rspec) fs_elems = root.findall(".//%s" % rspec_mod.FLOWSPACE_TAG) def add_switches(elem, switches): for s in switches: et.SubElement( elem, rspec_mod.SWITCH_TAG, { rspec_mod.URN: rspec_mod._dpid_to_urn(s.datapath_id), }, ) add_switches(fs_elems[0], fs1_switches) add_switches(fs_elems[1], fs2_switches) resv_rspec = et.tostring(root) # Now add the switches into the slice and get the expected rspec # that will be returned def add_switch_slivers(rule, switches): for s in switches: ports = OpenFlowInterface.objects.filter(switch=s) for p in ports: sliver, _ = OpenFlowInterfaceSliver.objects.get_or_create( slice=slice, resource=p) rule.slivers.add(sliver) add_switch_slivers(r1, fs1_switches) add_switch_slivers(r2, fs2_switches) expected_resv_rspec = rspec_mod.create_resv_rspec(user, slice) # delete created state project.delete() user.delete() r1.delete() r2.delete() # create the slice using gapi ret_rspec = self.rpc.CreateSliver( self.slice_gid.get_urn(), [self.slice_cred], resv_rspec, {}, ) ret = order_rspec(ret_rspec) exp = order_rspec(expected_resv_rspec) self.assertEqual( ret, exp, "Expected:\n%s \nFound:\n%s" % (exp, ret), ) # check that the created state is what is expected self.assertEqual( GENISliceInfo.objects.all()[0].slice_urn, self.slice_gid.get_urn()) project = Project.objects.all()[0] self.assertEqual(project.name, proj_name) self.assertEqual(project.description, proj_desc) slice = Slice.objects.all()[0] self.assertEqual(slice.name, slice_name) self.assertEqual(slice.description, slice_desc) self.assertEqual(slice.project, project) self.assertEqual( long(time.mktime(slice.expiration_date.timetuple())), long(time.mktime(expiration.timetuple())), ) user = User.objects.get(username=username) self.assertEqual(user.first_name, firstname) self.assertEqual(user.last_name, lastname) self.assertEqual(user.email, email) user_profile= UserProfile.objects.all()[0] self.assertEqual(user_profile.affiliation, affiliation) self.assertEqual(user, user) r1 = FlowSpaceRule.objects.all()[0] r2 = FlowSpaceRule.objects.all()[1] def verif_rule(r, fs): for field in "dl_src", "dl_dst", "dl_type", \ "vlan_id", "nw_src", "nw_dst", "nw_proto", \ "tp_src", "tp_dst": if field in fs: self.assertEqual(fs[field][0], getattr(r, field+"_start")) self.assertEqual(fs[field][1], getattr(r, field+"_end")) else: self.assertEqual(None, getattr(r, field+"_start")) self.assertEqual(None, getattr(r, field+"_end")) verif_rule(r1, fs1) verif_rule(r2, fs2) # check the slivers in rules: make sure each rule has all the # the interfaces it is supposed to have. def verif_slivers(r, ports, switches): all_ports = [] all_ports.extend(ports) for s in switches: all_ports.extend(OpenFlowInterface.objects.filter(switch=s)) all_ports = set(all_ports) # check number of interfaces self.assertEqual(len(all_ports), r.slivers.count()) # check slivers for sliver in r.slivers.all(): self.assertTrue(sliver.resource.as_leaf_class() in all_ports) verif_slivers(r1, fs1_ports, fs1_switches) verif_slivers(r2, fs2_ports, fs2_switches) return ret_rspec