def save_connections(self): """ Create two unique unidirectional links between the two interfaces. @return: tuple of the created connections. If a connection is not created, None is returned for it. """ cnxn1, created = create_or_update( OpenFlowConnection, filter_attrs=dict( src_iface = self.cleaned_data["local_interface"], dst_iface = self.cleaned_data["remote_interface"], ), ) if not created: cnxn1 = None cnxn2, created = create_or_update( OpenFlowConnection, filter_attrs=dict( dst_iface = self.cleaned_data["local_interface"], src_iface = self.cleaned_data["remote_interface"], ), ) if not created: cnxn2 = None return (cnxn1, cnxn2)
def register_topology_callback(url, cookie, **kwargs): logger.debug("Called register topology callback") attrs = {'url': url, 'cookie': cookie} filter_attrs = {'username': kwargs['user'].username, 'om': kwargs['om']} create_or_update(DummyCallBackProxy, filter_attrs, attrs) return ""
def register_topology_callback(url, cookie, **kwargs): ''' Store some information for the topology callback. ''' from expedient.common import utils attrs = {'url': url, 'cookie': cookie} filter_attrs = {'username': kwargs['user'].username} utils.create_or_update(CallBackServerProxy, filter_attrs, attrs) return ""
def create_or_update_switches(aggregate, switches): """Create or update the switches in aggregate C{aggregate} with switches in C{switches}. C{switches} is a dict mapping datapath ids to list of ports. """ active_switch_ids = [] active_iface_ids = [] for dpid, ports in switches.items(): switch, _ = create_or_update( OpenFlowSwitch, filter_attrs=dict( datapath_id=dpid, ), new_attrs=dict( aggregate=aggregate, name=dpid, available=True, status_change_timestamp=datetime.now(), ) ) active_switch_ids.append(switch.id) for port in ports: # update the interfaces for this switch iface, _ = create_or_update( OpenFlowInterface, filter_attrs=dict( switch__datapath_id=dpid, port_num=port, ), new_attrs=dict( aggregate=aggregate, name="Port %s" % port, switch=switch, available=True, status_change_timestamp=datetime.now(), ), ) active_iface_ids.append(iface.id) # make all inactive switches and interfaces unavailable. OpenFlowInterface.objects.filter( aggregate=aggregate).exclude(id__in=active_iface_ids).update( available=False, status_change_timestamp=datetime.now()) OpenFlowSwitch.objects.filter( aggregate=aggregate).exclude(id__in=active_switch_ids).update( available=False, status_change_timestamp=datetime.now())
def _from_rspec(self, rspec): """ See L{GENIAggregate._from_rspec}. """ root = et.fromstring(rspec) # get all planet lab nodes in the rspec. node_elems = root.findall(".//node") active_node_pks = [] for elem in node_elems: node_id = elem.get("id", None) hostname = elem.findtext(".//hostname") # TODO: not interested if there's no node id and hostname if node_id and hostname: # Create/update a matching node. Put it in this aggregate. node, created = create_or_update( PlanetLabNode, filter_attrs=dict(name=hostname), new_attrs=dict(node_id=node_id, aggregate=self) ) active_node_pks.append(node.pk) logger.debug("Found node id %s name %s - created: %s" % ( node_id, hostname, created)) # make disappeared nodes unavailable # we filter by aggregate so we don't make a node unavailable # if it has moved to another aggregate. PlanetLabNode.objects.filter( aggregate__pk=self.pk).exclude(pk__in=active_node_pks).update( available=False, status_change_timestamp=datetime.now()) # save the RSpec self.rspec = rspec self.save()
def create_or_update_switches(aggregate, switches): """Create or update the switches in aggregate C{aggregate} with switches in C{switches}. C{switches} is a dict mapping datapath ids to list of ports. """ active_switch_ids = [] active_iface_ids = [] for dpid, ports in switches.items(): switch, _ = create_or_update( OpenFlowSwitch, filter_attrs=dict(datapath_id=dpid, ), new_attrs=dict( aggregate=aggregate, name=dpid, available=True, status_change_timestamp=datetime.now(), )) active_switch_ids.append(switch.id) for port in ports: # update the interfaces for this switch iface, _ = create_or_update( OpenFlowInterface, filter_attrs=dict( switch__datapath_id=dpid, port_num=port, ), new_attrs=dict( aggregate=aggregate, name="Port %s" % port, switch=switch, available=True, status_change_timestamp=datetime.now(), ), ) active_iface_ids.append(iface.id) # make all inactive switches and interfaces unavailable. OpenFlowInterface.objects.filter(aggregate=aggregate).exclude( id__in=active_iface_ids).update(available=False, status_change_timestamp=datetime.now()) OpenFlowSwitch.objects.filter(aggregate=aggregate).exclude( id__in=active_switch_ids).update( available=False, status_change_timestamp=datetime.now())
def create_slice(slice_id, project_name, project_description, slice_name, slice_description, controller_url, owner_email, owner_password, switch_slivers, **kwargs): logger.debug("reserve_slice") logger.debug(" slice_id: %s" % slice_id) logger.debug(" project_name: %s" % project_name) logger.debug(" project_desc: %s" % project_description) logger.debug(" slice_name: %s" % slice_name) logger.debug(" slice_desc: %s" % slice_description) logger.debug(" controller: %s" % controller_url) logger.debug(" owner_email: %s" % owner_email) logger.debug(" owner_pass: %s" % owner_password) logger.debug(pformat(" slivers: %s" % switch_slivers)) # update or create the slice slice = create_or_update( DummyOMSlice, filter_attrs=dict( slice_id=slice_id, om=kwargs['om'], ), new_attrs=dict( project_name=project_name, project_description=project_description, slice_name=slice_name, slice_description=slice_description, controller_url=controller_url, owner_email=owner_email, owner_password=owner_password, switch_slivers=b64encode(pickle.dumps(switch_slivers)), ), ) return { 'error_msg': "", 'switches': [], }
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 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_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 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