def add_unit(self, *, u: Unit): """ Add a unit @parm u unit """ if u.get_id() not in self.units: self.units[u.get_id()] = u
def post(self, *, u: Unit, message: str): """ Post the notice @param u unit @param message message """ self.logger.error(message) u.add_notice(notice=message)
def fail_modify_no_update(self, *, unit: Unit, message: str, e: Exception = None): self.logger.error(message) if e: self.logger.error(e) unit.fail_on_modify(message=message, exception=e)
def fail_and_update(self, *, unit: Unit, message: str, e: Exception): self.logger.error(message) self.logger.error(str(e)) try: unit.fail(message=message, exception=e) self.db.update_unit(u=unit) except Exception as ex: self.logger.error("could not update unit in database") self.logger.error(ex)
def modify_unit(self, *, u: Unit): """ Modify a unit @param u unit """ try: u.start_modify() self.plugin.modify(reservation=self.reservation, u=u) except Exception as e: self.fail(u=u, message="Modify for node failed", e=e)
def create_unit(include_pci: bool = True, include_image: bool = True, include_name: bool = True, include_instance_name: bool = False) -> Unit: """ Create a unit :param include_pci: :param include_image: :param include_name: :param include_instance_name: :return: """ u = Unit(rid=ID(uid='rid-1')) sliver = NodeSliver() cap = Capacities() cap.set_fields(core=2, ram=8, disk=10) sliver.set_properties(type=NodeType.VM, site="RENC", capacity_allocations=cap) sliver.label_allocations = Labels().set_fields( instance_parent="renc-w3") catalog = InstanceCatalog() instance_type = catalog.map_capacities_to_instance(cap=cap) cap_hints = CapacityHints().set_fields(instance_type=instance_type) sliver.set_properties( capacity_hints=cap_hints, capacity_allocations=catalog.get_instance_capacities( instance_type=instance_type)) if include_name: sliver.set_properties(name="n2") if include_image: sliver.set_properties(image_type='qcow2', image_ref='default_fedora') if include_pci: component = ComponentSliver() labels = Labels() labels.set_fields(bdf=["0000:41:00.0", "0000:41:00.1"]) component.set_properties(type=ComponentType.SmartNIC, model='ConnectX-5', name='nic1', label_allocations=labels) #labels.set_fields(bdf="0000:81:00.0") #component.set_properties(type=ComponentType.GPU, model='Tesla T4', name='nic12', label_allocations=labels) sliver.attached_components_info = AttachedComponentsInfo() sliver.attached_components_info.add_device(device_info=component) if include_instance_name: sliver.label_allocations.set_fields(instance="instance-001") u.set_sliver(sliver=sliver) return u
def fail(self, *, u: Unit, message: str, e: Exception = None): """ Fail a unit and log error message @param u unit @param message message @param e exception """ self.logger.error(message) if e is not None: self.logger.error(e) u.fail(message=message, exception=e)
def transfer_out(self, *, u: Unit): """ Transfer a unit @param u unit to be transferred """ if u.transfer_out_started: return try: u.start_close() self.plugin.transfer_out(reservation=self.reservation, unit=u) except Exception as e: self.fail(u=u, message="tranferOut error", e=e)
def assign( self, *, reservation: ABCAuthorityReservation, delegation_name: str, graph_node: BaseSliver, existing_reservations: List[ABCReservationMixin]) -> ResourceSet: """ Assign a reservation :param reservation: reservation :param delegation_name: Name of delegation serving the request :param graph_node: ARM Graph Node serving the reservation :param existing_reservations: Existing Reservations served by the same ARM node :return: ResourceSet with updated sliver annotated with properties :raises: AuthorityException in case the request cannot be satisfied """ reservation.set_send_with_deficit(value=True) requested = reservation.get_requested_resources().get_sliver() self.__dump_sliver(sliver=requested) if not isinstance(requested, NetworkServiceSliver): raise AuthorityException( f"Invalid resource type {requested.get_type()}") current = reservation.get_resources() resource_type = ResourceType(resource_type=str(requested.get_type())) gained = None lost = None if current is None: self.logger.debug("check if sliver can be provisioned") # FIXME Add validation to check ticketed sliver against ARM # Refer Network Node Control for reference self.logger.debug( f"Slice properties: {reservation.get_slice().get_config_properties()}" ) unit = Unit( rid=reservation.get_reservation_id(), slice_id=reservation.get_slice_id(), actor_id=self.authority.get_guid(), sliver=requested, rtype=resource_type, properties=reservation.get_slice().get_config_properties()) gained = UnitSet(plugin=self.authority.get_plugin(), units={unit.reservation_id: unit}) else: # FIXME: handle modify self.logger.info( f"Extend Lease for now, no modify supported res# {reservation}" ) return current result = ResourceSet(gained=gained, lost=lost, rtype=resource_type) result.set_sliver(sliver=requested) return result
def create_sliver(self, name: str, pci_address: str, gpu_name: str) -> Unit: u = Unit(rid=ID(uid=name)) sliver = NodeSliver() cap = Capacities(core=2, ram=6, disk=10) sliver.set_properties(type=NodeType.VM, site="UKY", capacity_allocations=cap) sliver.label_allocations = Labels(instance_parent="uky-w2.fabric-testbed.net") catalog = InstanceCatalog() instance_type = catalog.map_capacities_to_instance(cap=cap) cap_hints = CapacityHints(instance_type=instance_type) sliver.set_properties(capacity_hints=cap_hints, capacity_allocations=catalog.get_instance_capacities(instance_type=instance_type)) sliver.set_properties(name=name) sliver.set_properties(image_type='qcow2', image_ref='default_ubuntu_20') component = ComponentSliver() labels = Labels(bdf=pci_address) component.set_properties(type=ComponentType.GPU, model='Tesla T4', name=gpu_name, label_allocations=labels) sliver.attached_components_info = AttachedComponentsInfo() sliver.attached_components_info.add_device(device_info=component) u.set_sliver(sliver=sliver) u.set_resource_type(rtype=ResourceType(resource_type=NodeType.VM.name)) return u
def test_d_add_update_get_unit(self): actor = self.prepare_actor_database() db = actor.get_plugin().get_database() slice_obj = SliceFactory.create(slice_id=ID(), name="slice-1") db.add_slice(slice_object=slice_obj) rset = ResourceSet() term = Term(start=datetime.now(), end=datetime.now().replace(minute=20)) res = AuthorityReservationFactory.create(resources=rset, term=term, slice_obj=slice_obj, rid=ID()) db.add_reservation(reservation=res) rtype = ResourceType(resource_type="12") u = Unit(rid=res.get_reservation_id(), slice_id=slice_obj.get_slice_id(), actor_id=actor.get_guid()) u.set_resource_type(rtype=rtype) db.add_unit(u=u) self.assertIsNotNone(db.get_unit(uid=u.get_id()))
def transfer_in(self, *, unit: Unit): """ Transfer in a unit @param unit unit """ try: if unit.start_prime(): unit.set_reservation(reservation=self.reservation) unit.set_slice_id(slice_id=self.reservation.get_slice_id()) unit.set_actor_id(actor_id=self.plugin.get_actor().get_guid()) self.plugin.transfer_in(reservation=self.reservation, unit=unit) else: self.post( u=unit, message="Unit cannot be transferred., State={}".format( unit.get_state())) except Exception as e: self.fail(u=unit, message="Transfer in for node failed", e=e)
def translate_unit_from_avro(*, unit_avro: UnitAvro) -> Unit: unit = Unit(rid=ID(uid=unit_avro.reservation_id)) if unit_avro.properties is not None: unit.properties = unit_avro.properties if unit_avro.rtype is not None: unit.rtype = ResourceType(resource_type=unit.rtype) if unit_avro.parent_id is not None: unit.parent_id = ID(uid=unit_avro.parent_id) if unit_avro.slice_id is not None: unit.slice_id = ID(uid=unit_avro.slice_id) if unit_avro.actor_id is not None: unit.actor_id = ID(uid=unit_avro.actor_id) if unit_avro.state is not None: unit.state = UnitState(unit_avro.state) return unit
def test_PortMirror(self): # create a NetworkService sliver for FABNetv6 prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop, process_lock=threading.Lock()) # # create a network sliver for FABNetv4 and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('PortMirror-UKY') sliver.set_type(ServiceType.PortMirror) sliver.set_layer(NSLayer.L2) # mirror_port is the name of the port being mirrored - actual name the way # service definition needs it. It comes directly from ASM network service sliver # whatever the right name is - user must to know it when creating a slice sliver.mirror_port = "TwentyFiveGigE0/0/0/24" # direction also comes from ASM network service sliver sliver.mirror_direction = MirrorDirection.Both # # interface to which the mirrored traffic is directed to # it is in the slice (ASM) model, the same way all other interfaces for network services are. # stp_to = InterfaceSliver() stp_to.set_name('Interface_To_Which_We_Send_Mirrored_Traffic') stp_to.set_type(InterfaceType.ServicePort) sliver_labels = Labels(local_name='TwentyFiveGigE0/0/0/23/1', device_name='lbnl-data-sw') sliver_capacities = Capacities(bw=2000) stp_to.set_labels(sliver_labels) stp_to.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(stp_to) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_PortMirror') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK)
def test_FABNetv6(self): # create a NetworkService sliver for FABNetv6 prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop, process_lock=threading.Lock()) # # create a network sliver for FABNetv4 and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L3-UKY-IPv6') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.FABNetv6) sliver.set_layer(NSLayer.L3) # this is the gateway with the IP range picked for this sliver in this slice on this site # can also be specified with ipv6/ipv6_subnet and mac is optional for both. # Q: does that mean that the advertisement needs to maintain information about multiple # subnet, gateway and mac tuples for each site? sliver.set_gateway( Gateway( Labels(ipv6="2602:FCFB:0001::1", ipv6_subnet="2602:FCFB:0001::/64"))) # # create a small number of Interface slivers, set their properties and link to service # # # First interface - let's assume it is SR-IOV # isl1 = InterfaceSliver() # the name is normally set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) # since this is SR-IOV, orchestrator picks VLAN for this function based on info in advertisement # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='121', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities = Capacities(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (let's assume this is a dedicated card) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) # Q: who and how picks the VLAN in this case? I think we discussed having an advertised pool of 'Layer 3 # vlans' which need to be kept track of and this would be one of them # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='1001', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') sliver_capacities = Capacities(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_FABNetv6') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK)
def test_L2Bridge(self): # create a NetworkService sliver for L2Bridge prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L2BridgeServiceTest') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.L2Bridge) sliver.set_layer(NSLayer.L2) # Interface properties # # The service definitions make a distinction between interface which requires # type = parse(InterfaceSliver.Labels.local_name) # id = parse(InterfaceSliver.Labels.local_name) # outervlan = InterfaceSliver.Labels.vlan # innervlan = InterfaceSliver.Labels.inner_vlan # bw = InterfaceSliver.Capacities.bw (0 - best-effort) # burst size = InterfaceSliver.Capacities.burst_size # # and STP which in addition also requires NSO device name. # In deep network sliver NSO Device name goes on *each* interface, then handler.create can parse # out the interfaces and figure out which STP each interface goes with based on that. # NSO device name = InterfaceSliver.Labels.device_name # # The properties of InterfaceSlivers noted above must be copied by Orchestrator from various places # a) the switch TrunkPort port the ASM ServicePort maps to in CBM # b) the Shared or Dedicated ASM port on the card the ServicePort peers with in ASM # c) the Shared or Dedicated CBM port the peer ASM port maps to # Below for each property comments indicate where they come from by a, b, c # Orchestrator determines peer ports in ASM (between ServicePort and corresponding Shared/Dedicated card port) # and sets nodemaps to point from ASM ServicePort to corresponding CBM TrunkPort # as well as between Shared/Dedicated ASM port on the NIC and the corresponding CBM Shared/Dedicated port # # create a small number of Interface slivers, set their properties and link to service # isl1 = InterfaceSliver() # the name is set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # inner_vlan - not used for now - user would fill it in directly on the sliver Labels - # need to discuss. # sl1labs.set_fields(inner_vlan='3') # vlan - source: (c) sliver_labels.set_fields(vlan='100') # local_name source: (a) sliver_labels.set_fields(local_name='HundredGigE0/0/0/17') # NSO device name source: (a) - need to find the owner switch of the network service in CBM # and take its .name or labels.local_name sliver_labels.set_fields(device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities.set_fields(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (comments for field info origin omitted below) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # sliver_labels.set_fields(vlan='102') sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/1') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2Bridge') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK)
def setUp(self) -> None: self.unit = Unit(rid=ID(uid="rid-1"))
class TestNetHandler(unittest.TestCase): logger = logging.getLogger(__name__) log_format = \ '%(asctime)s - %(name)s - {%(filename)s:%(lineno)d} - [%(threadName)s] - %(levelname)s - %(message)s' logging.basicConfig(handlers=[logging.StreamHandler()], format=log_format, force=True) def setUp(self) -> None: self.unit = Unit(rid=ID(uid="rid-1")) def test_L2Bridge(self): # create a NetworkService sliver for L2Bridge prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L2BridgeServiceTest') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.L2Bridge) sliver.set_layer(NSLayer.L2) # Interface properties # # The service definitions make a distinction between interface which requires # type = parse(InterfaceSliver.Labels.local_name) # id = parse(InterfaceSliver.Labels.local_name) # outervlan = InterfaceSliver.Labels.vlan # innervlan = InterfaceSliver.Labels.inner_vlan # bw = InterfaceSliver.Capacities.bw (0 - best-effort) # burst size = InterfaceSliver.Capacities.burst_size # # and STP which in addition also requires NSO device name. # In deep network sliver NSO Device name goes on *each* interface, then handler.create can parse # out the interfaces and figure out which STP each interface goes with based on that. # NSO device name = InterfaceSliver.Labels.device_name # # The properties of InterfaceSlivers noted above must be copied by Orchestrator from various places # a) the switch TrunkPort port the ASM ServicePort maps to in CBM # b) the Shared or Dedicated ASM port on the card the ServicePort peers with in ASM # c) the Shared or Dedicated CBM port the peer ASM port maps to # Below for each property comments indicate where they come from by a, b, c # Orchestrator determines peer ports in ASM (between ServicePort and corresponding Shared/Dedicated card port) # and sets nodemaps to point from ASM ServicePort to corresponding CBM TrunkPort # as well as between Shared/Dedicated ASM port on the NIC and the corresponding CBM Shared/Dedicated port # # create a small number of Interface slivers, set their properties and link to service # isl1 = InterfaceSliver() # the name is set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # inner_vlan - not used for now - user would fill it in directly on the sliver Labels - # need to discuss. # sl1labs.set_fields(inner_vlan='3') # vlan - source: (c) sliver_labels.set_fields(vlan='100') # local_name source: (a) sliver_labels.set_fields(local_name='HundredGigE0/0/0/17') # NSO device name source: (a) - need to find the owner switch of the network service in CBM # and take its .name or labels.local_name sliver_labels.set_fields(device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities.set_fields(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (comments for field info origin omitted below) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # sliver_labels.set_fields(vlan='102') sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/1') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2Bridge') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_L2Bridge_Hairpin(self): # create a NetworkService sliver for L2Bridge prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L2-UKY-Hairpin') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.L2Bridge) sliver.set_layer(NSLayer.L2) # Interface properties # # The service definitions make a distinction between interface which requires # type = parse(InterfaceSliver.Labels.local_name) # id = parse(InterfaceSliver.Labels.local_name) # outervlan = InterfaceSliver.Labels.vlan # innervlan = InterfaceSliver.Labels.inner_vlan # bw = InterfaceSliver.Capacities.bw (0 - best-effort) # burst size = InterfaceSliver.Capacities.burst_size # # and STP which in addition also requires NSO device name. # In deep network sliver NSO Device name goes on *each* interface, then handler.create can parse # out the interfaces and figure out which STP each interface goes with based on that. # NSO device name = InterfaceSliver.Labels.device_name # # The properties of InterfaceSlivers noted above must be copied by Orchestrator from various places # a) the switch TrunkPort port the ASM ServicePort maps to in CBM # b) the Shared or Dedicated ASM port on the card the ServicePort peers with in ASM # c) the Shared or Dedicated CBM port the peer ASM port maps to # Below for each property comments indicate where they come from by a, b, c # Orchestrator determines peer ports in ASM (between ServicePort and corresponding Shared/Dedicated card port) # and sets nodemaps to point from ASM ServicePort to corresponding CBM TrunkPort # as well as between Shared/Dedicated ASM port on the NIC and the corresponding CBM Shared/Dedicated port # # create a small number of Interface slivers, set their properties and link to service # isl1 = InterfaceSliver() # the name is set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # inner_vlan - not used for now - user would fill it in directly on the sliver Labels - # need to discuss. # sl1labs.set_fields(inner_vlan='3') # vlan - source: (c) sliver_labels.set_fields(vlan='101') # local_name source: (a) sliver_labels.set_fields(local_name='HundredGigE0/0/0/5') # NSO device name source: (a) - need to find the owner switch of the network service in CBM # and take its .name or labels.local_name sliver_labels.set_fields(device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities.set_fields(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (comments for field info origin omitted below) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() sliver_labels.set_fields(vlan='102') sliver_labels.set_fields(inner_vlan='200') sliver_labels.set_fields(local_name='HundredGigE0/0/0/5') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2Bridge') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_L2PTP(self): # create a NetworkService sliver for L2PTP prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name - can we use the sliver name - only guaranteed unique in the slice sliver.set_name('L2PTPServiceTest') sliver.set_type(ServiceType.L2PTP) sliver.set_layer(NSLayer.L2) # ERO # first declare a path. Each path is a list of somethings. a2z and z2a maintained separately within Path ero_path = Path() ero_path.set_symmetric(["10.1.1.1", "10.1.1.2"]) # default is loose ERO, set strict=True if want otherwise ero = ERO(strict=False) ero.set(ero_path) sliver.set_ero(ero) # # STP_A interface # stp_a = InterfaceSliver() stp_a.set_name('Interface1') stp_a.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() sliver_labels.set_fields(vlan='235') sliver_labels.set_fields(local_name='HundredGigE0/0/0/17') sliver_labels.set_fields(device_name='renc-data-sw') sliver_capacities.set_fields(bw=1000) stp_a.set_labels(sliver_labels) stp_a.set_capacities(sliver_capacities) # # STP_Z interface # stp_z = InterfaceSliver() stp_z.set_name('Interface2') stp_z.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() sliver_labels.set_fields(vlan='235') sliver_labels.set_fields(local_name='HundredGigE0/0/0/13') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1000) stp_z.set_labels(sliver_labels) stp_z.set_capacities(sliver_capacities) # create interface info object, add interfaces to it ifi = InterfaceInfo() ifi.add_interface(stp_a) ifi.add_interface(stp_z) # All of this happens automagically in FIM sliver.interface_info = ifi uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2PTP') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_L2STS(self): # create a NetworkService sliver for L2STS prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name - can we use the sliver name - only guaranteed unique in the slice sliver.set_name('L2STSServiceTest') sliver.set_type(ServiceType.L2STS) sliver.set_layer(NSLayer.L2) # ERO # first declare a path. Each path is a list of somethings. a2z and z2a maintained separately within Path ero_path = Path() ero_path.set_symmetric(["10.1.1.1", "10.1.1.2"]) # default is loose ERO, set strict=True if want otherwise ero = ERO(strict=False) ero.set(ero_path) sliver.set_ero(ero) # # site A interfaces # stp_a1 = InterfaceSliver() stp_a1.set_name('Interface_A1') stp_a1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # untagged w/o vlan label set sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/1') sliver_labels.set_fields(device_name='lbnl-data-sw') sliver_capacities.set_fields(bw=2000) stp_a1.set_labels(sliver_labels) stp_a1.set_capacities(sliver_capacities) # # site Z interfaces # stp_z1 = InterfaceSliver() stp_z1.set_name('Interface_Z1') stp_z1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() sliver_labels.set_fields(vlan='235') sliver_labels.set_fields(local_name='HundredGigE0/0/0/13') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1000) stp_z1.set_labels(sliver_labels) stp_z1.set_capacities(sliver_capacities) stp_z2 = InterfaceSliver() stp_z2.set_name('Interface_Z2') stp_z2.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # untagged w/o vlan label set sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/2') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1000) stp_z2.set_labels(sliver_labels) stp_z2.set_capacities(sliver_capacities) # create interface info object, add interfaces to it ifi = InterfaceInfo() ifi.add_interface(stp_a1) ifi.add_interface(stp_z1) ifi.add_interface(stp_z2) # All of this happens automagically in FIM sliver.interface_info = ifi uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2STS') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_FABNetv4(self): # create a NetworkService sliver for FABNetv4 prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop, process_lock=threading.Lock()) # # create a network sliver for FABNetv4 and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L3-UKY-IPv4') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.FABNetv4) sliver.set_layer(NSLayer.L3) # this is the gateway with the IP range picked for this sliver in this slice on this site # can also be specified with ipv6/ipv6_subnet and mac is optional for both. # Q: does that mean that the advertisement needs to maintain information about multiple # subnet, gateway and mac tuples for each site? sliver.set_gateway( Gateway( Labels(ipv4="10.128.128.254", ipv4_subnet="10.128.128.0/24"))) # # create a small number of Interface slivers, set their properties and link to service # # # First interface - let's assume it is SR-IOV # isl1 = InterfaceSliver() # the name is normally set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) # since this is SR-IOV, orchestrator picks VLAN for this function based on info in advertisement # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='121', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities = Capacities(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (let's assume this is a dedicated card) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) # Q: who and how picks the VLAN in this case? I think we discussed having an advertised pool of 'Layer 3 # vlans' which need to be kept track of and this would be one of them # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='1001', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') sliver_capacities = Capacities(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_FABNetv4') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_FABNetv6(self): # create a NetworkService sliver for FABNetv6 prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop, process_lock=threading.Lock()) # # create a network sliver for FABNetv4 and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('L3-UKY-IPv6') # if service name global uniqueness is a requirement use Labels.local_name for that (optional) # e.g. concatenate name + res id (or another unique id) # sliver.set_labels(Labels().set_fields(local_name='test-l2bridge-shortname')) # per @xiyang he uses unit id for service name so this is not needed. sliver.set_type(ServiceType.FABNetv6) sliver.set_layer(NSLayer.L3) # this is the gateway with the IP range picked for this sliver in this slice on this site # can also be specified with ipv6/ipv6_subnet and mac is optional for both. # Q: does that mean that the advertisement needs to maintain information about multiple # subnet, gateway and mac tuples for each site? sliver.set_gateway( Gateway( Labels(ipv6="2602:FCFB:0001::1", ipv6_subnet="2602:FCFB:0001::/64"))) # # create a small number of Interface slivers, set their properties and link to service # # # First interface - let's assume it is SR-IOV # isl1 = InterfaceSliver() # the name is normally set by FIM as '-' concatenation of service name isl1.set_name('Interface1') # this will be a ServicePort in the network service sliver. It is created by FIM automatically when # the user adds a NetworkService to the ASM. The name is set by the FIM as '-' concatenation of service # name and peer interface sliver name. isl1.set_type(InterfaceType.ServicePort) # since this is SR-IOV, orchestrator picks VLAN for this function based on info in advertisement # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='121', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') # capacities (bw in Gbps, burst size is in Mbytes) source: (b) sliver_capacities = Capacities(bw=1) # assign labels and capacities isl1.set_labels(sliver_labels) isl1.set_capacities(sliver_capacities) # # Second interface (let's assume this is a dedicated card) # isl2 = InterfaceSliver() isl2.set_name('Interface2') isl2.set_type(InterfaceType.ServicePort) # Q: who and how picks the VLAN in this case? I think we discussed having an advertised pool of 'Layer 3 # vlans' which need to be kept track of and this would be one of them # other information is done in the same way it is done for L2 services sliver_labels = Labels(vlan='1001', local_name='HundredGigE0/0/0/5', device_name='uky-data-sw') sliver_capacities = Capacities(bw=1) isl2.set_labels(sliver_labels) isl2.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(isl1) ifi.add_interface(isl2) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_FABNetv6') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) def test_PortMirror(self): # create a NetworkService sliver for FABNetv6 prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop, process_lock=threading.Lock()) # # create a network sliver for FABNetv4 and its interfaces # sliver = NetworkServiceSliver() # service name (set by user) - only guaranteed unique within a slice sliver.set_name('PortMirror-UKY') sliver.set_type(ServiceType.PortMirror) sliver.set_layer(NSLayer.L2) # mirror_port is the name of the port being mirrored - actual name the way # service definition needs it. It comes directly from ASM network service sliver # whatever the right name is - user must to know it when creating a slice sliver.mirror_port = "TwentyFiveGigE0/0/0/24" # direction also comes from ASM network service sliver sliver.mirror_direction = MirrorDirection.Both # # interface to which the mirrored traffic is directed to # it is in the slice (ASM) model, the same way all other interfaces for network services are. # stp_to = InterfaceSliver() stp_to.set_name('Interface_To_Which_We_Send_Mirrored_Traffic') stp_to.set_type(InterfaceType.ServicePort) sliver_labels = Labels(local_name='TwentyFiveGigE0/0/0/23/1', device_name='lbnl-data-sw') sliver_capacities = Capacities(bw=2000) stp_to.set_labels(sliver_labels) stp_to.set_capacities(sliver_capacities) # create interface info object, add populated interfaces to it ifi = InterfaceInfo() ifi.add_interface(stp_to) # add interface info object to sliver. All of this happens automagically normally sliver.interface_info = ifi # set a fake unit reservation uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_PortMirror') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service (create needs to parse out sliver information # into exact parameters the service ansible script needs) # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK)
def test_L2STS(self): # create a NetworkService sliver for L2STS prop = { AmConstants.CONFIG_PROPERTIES_FILE: '../config/net_handler_config.yml' } handler = NetHandler(logger=self.logger, properties=prop) # # create a network sliver for L2Bridge and its interfaces # sliver = NetworkServiceSliver() # service name - can we use the sliver name - only guaranteed unique in the slice sliver.set_name('L2STSServiceTest') sliver.set_type(ServiceType.L2STS) sliver.set_layer(NSLayer.L2) # ERO # first declare a path. Each path is a list of somethings. a2z and z2a maintained separately within Path ero_path = Path() ero_path.set_symmetric(["10.1.1.1", "10.1.1.2"]) # default is loose ERO, set strict=True if want otherwise ero = ERO(strict=False) ero.set(ero_path) sliver.set_ero(ero) # # site A interfaces # stp_a1 = InterfaceSliver() stp_a1.set_name('Interface_A1') stp_a1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # untagged w/o vlan label set sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/1') sliver_labels.set_fields(device_name='lbnl-data-sw') sliver_capacities.set_fields(bw=2000) stp_a1.set_labels(sliver_labels) stp_a1.set_capacities(sliver_capacities) # # site Z interfaces # stp_z1 = InterfaceSliver() stp_z1.set_name('Interface_Z1') stp_z1.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() sliver_labels.set_fields(vlan='235') sliver_labels.set_fields(local_name='HundredGigE0/0/0/13') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1000) stp_z1.set_labels(sliver_labels) stp_z1.set_capacities(sliver_capacities) stp_z2 = InterfaceSliver() stp_z2.set_name('Interface_Z2') stp_z2.set_type(InterfaceType.ServicePort) sliver_labels = Labels() sliver_capacities = Capacities() # untagged w/o vlan label set sliver_labels.set_fields(local_name='TwentyFiveGigE0/0/0/23/2') sliver_labels.set_fields(device_name='uky-data-sw') sliver_capacities.set_fields(bw=1000) stp_z2.set_labels(sliver_labels) stp_z2.set_capacities(sliver_capacities) # create interface info object, add interfaces to it ifi = InterfaceInfo() ifi.add_interface(stp_a1) ifi.add_interface(stp_z1) ifi.add_interface(stp_z2) # All of this happens automagically in FIM sliver.interface_info = ifi uid = uuid.uuid3(uuid.NAMESPACE_DNS, 'test_L2STS') self.unit = Unit(rid=ID(uid=str(uid))) self.unit.set_sliver(sliver=sliver) # # create a service # r, updated_unit = handler.create(unit=self.unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_CREATE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK) time.sleep(30) # # delete - need to make sure the updated unit has the right info to delete the service # r, updated_unit = handler.delete(updated_unit) self.assertEqual(r[Constants.PROPERTY_TARGET_NAME], Constants.TARGET_DELETE) self.assertEqual(r[Constants.PROPERTY_ACTION_SEQUENCE_NUMBER], 0) self.assertEqual(r[Constants.PROPERTY_TARGET_RESULT_CODE], Constants.RESULT_CODE_OK)
def create_unit(include_pci: bool = True, include_image: bool = True, include_name: bool = True, include_instance_name: bool = False, include_ns: bool = False) -> Unit: """ Create a unit :param include_pci: :param include_image: :param include_name: :param include_instance_name: :param include_ns: :return: """ u = Unit(rid=ID(uid="rid-1")) sliver = NodeSliver() cap = Capacities() cap.set_fields(core=4, ram=64, disk=500) catalog = InstanceCatalog() instance_type = catalog.map_capacities_to_instance(cap=cap) cap_hints = CapacityHints().set_fields(instance_type=instance_type) sliver.set_properties( type=NodeType.VM, site="RENC", capacity_hints=cap_hints, capacity_allocations=catalog.get_instance_capacities( instance_type=instance_type)) sliver.label_allocations = Labels().set_fields( instance_parent="renc-w1.fabric-testbed.net") if include_name: sliver.set_properties(name="n1") if include_image: sliver.set_properties(image_type='qcow2', image_ref='default_centos_8') if include_pci: component = ComponentSliver() labels = Labels() labels.set_fields(bdf=["0000:41:00.0", "0000:41:00.1"]) component.set_properties(type=ComponentType.SmartNIC, model='ConnectX-6', name='nic1', label_allocations=labels) sliver.attached_components_info = AttachedComponentsInfo() sliver.attached_components_info.add_device(device_info=component) if include_instance_name: sliver.label_allocations.set_fields(instance="instance-001") if include_ns: sliver.network_service_info = NetworkServiceInfo() ns = NetworkServiceSliver() ns.interface_info = InterfaceInfo() ifs1 = InterfaceSliver() c = Capacities() c.bw = 100 c.unit = 1 l1 = Labels() l1.ipv4 = '192.168.11.3' l1.vlan = '200' l1.local_name = 'p1' la_1 = Labels() la_1.mac = '0C:42:A1:EA:C7:51' la_1.vlan = '200' ifs1.capacities = c ifs1.labels = l1 ifs1.label_allocations = la_1 ifs2 = InterfaceSliver() ifs2.capacities = c l2 = Labels() l2.ipv4 = '192.168.11.2' l2.local_name = 'p2' la_2 = Labels() la_2.mac = '0C:42:A1:EA:C7:52' ifs2.labels = l2 ifs2.label_allocations = la_1 ns.interface_info.interfaces = {'ifs1': ifs1, 'ifs2': ifs2} sliver.network_service_info.network_services = {'ns1': ns} u.set_sliver(sliver=sliver) return u
def assign( self, *, reservation: ABCAuthorityReservation, delegation_name: str, graph_node: BaseSliver, existing_reservations: List[ABCReservationMixin]) -> ResourceSet: """ Assign a reservation :param reservation: reservation :param delegation_name: Name of delegation serving the request :param graph_node: ARM Graph Node serving the reservation :param existing_reservations: Existing Reservations served by the same ARM node :return: ResourceSet with updated sliver annotated with properties :raises: AuthorityException in case the request cannot be satisfied """ if graph_node.capacity_delegations is None or reservation is None: raise AuthorityException(Constants.INVALID_ARGUMENT) delegated_capacities = graph_node.get_capacity_delegations() available_delegated_capacity = FimHelper.get_delegation( delegated_capacities=delegated_capacities, delegation_name=delegation_name) if available_delegated_capacity is None: raise AuthorityException( f"Allocated node {graph_node.node_id} does not have delegation: {delegation_name}" ) reservation.set_send_with_deficit(value=True) requested = reservation.get_requested_resources().get_sliver() if not isinstance(requested, NodeSliver): raise AuthorityException( f"Invalid resource type {requested.get_type()}") current = reservation.get_resources() resource_type = ResourceType(resource_type=str(requested.get_type())) gained = None lost = None if current is None: # Check if Capacities can be satisfied by Delegated Capacities self.__check_capacities( rid=reservation.get_reservation_id(), requested_capacities=requested.get_capacity_allocations(), available_capacities=available_delegated_capacity, existing_reservations=existing_reservations) # Check if Capacities can be satisfied by Capacities self.__check_capacities( rid=reservation.get_reservation_id(), requested_capacities=requested.get_capacity_allocations(), available_capacities=graph_node.get_capacities(), existing_reservations=existing_reservations) # Check components # Check if Components can be allocated if requested.attached_components_info is not None: self.__check_components( rid=reservation.get_reservation_id(), requested_components=requested.attached_components_info, graph_node=graph_node, existing_reservations=existing_reservations) self.logger.debug( f"Slice properties: {reservation.get_slice().get_config_properties()}" ) unit = Unit( rid=reservation.get_reservation_id(), slice_id=reservation.get_slice_id(), actor_id=self.authority.get_guid(), sliver=requested, rtype=resource_type, properties=reservation.get_slice().get_config_properties()) gained = UnitSet(plugin=self.authority.get_plugin(), units={unit.reservation_id: unit}) else: # FIX ME: handle modify self.logger.info( f"Extend Lease for now, no modify supported res# {reservation}" ) return current result = ResourceSet(gained=gained, lost=lost, rtype=resource_type) result.set_sliver(sliver=requested) return result
def fail(self, *, u: Unit, message: str, e: Exception = None): if e is not None: self.logger.error(e) else: self.logger.error(message) u.fail(message=message, exception=e)
def test_unit(self): rid = ID() u1 = Unit(rid=rid) self.assertIsNotNone(u1.get_id()) self.assertEqual(UnitState.DEFAULT, u1.get_state()) self.assertIsNone(u1.get_property(name="foo")) self.assertIsNone(u1.get_parent_id()) self.assertIsNotNone(u1.get_reservation_id()) self.assertIsNone(u1.get_slice_id()) self.assertIsNone(u1.get_actor_id()) self.assertEqual(0, u1.get_sequence()) u1.increment_sequence() self.assertEqual(1, u1.get_sequence()) u1.decrement_sequence() self.assertEqual(0, u1.get_sequence()) db = self.make_actor_database() slice_id = ID() from fabric_cf.actor.core.container.globals import GlobalsSingleton actor_id = GlobalsSingleton.get().get_container().get_actor().get_guid( ) slice_obj = SliceFactory.create(slice_id=slice_id, name="test_slice") db.add_slice(slice_object=slice_obj) reservation = ClientReservationFactory.create(rid=rid, slice_object=slice_obj) u1.set_actor_id(actor_id=actor_id) u1.set_reservation(reservation=reservation) u1.set_slice_id(slice_id=slice_id) db.add_reservation(reservation=reservation) u1.start_prime() self.assertEqual(UnitState.PRIMING, u1.get_state()) u1.set_property(name="foo", value="bar") u1.increment_sequence() u1.increment_sequence() resource_type = ResourceType(resource_type="1") u1.set_resource_type(rtype=resource_type) self.assertEqual(2, u1.get_sequence()) db.add_unit(u=u1) self.assertIsNotNone(db.get_unit(uid=rid))