예제 #1
0
 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
예제 #2
0
 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)
예제 #5
0
 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)
예제 #6
0
    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
예제 #7
0
    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)
예제 #8
0
    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
예제 #11
0
    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()))
예제 #12
0
 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)
예제 #13
0
    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
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
    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)
예제 #17
0
 def setUp(self) -> None:
     self.unit = Unit(rid=ID(uid="rid-1"))
예제 #18
0
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)
예제 #19
0
    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)
예제 #20
0
    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)
예제 #23
0
    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))