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
Exemple #2
0
    def allocate_ifs(
            self, *, requested_ns: NetworkServiceSliver,
            requested_ifs: InterfaceSliver, owner_switch: NodeSliver,
            mpls_ns: NetworkServiceSliver, bqm_ifs_id: str,
            existing_reservations: List[ABCReservationMixin]
    ) -> InterfaceSliver:
        """
        Allocate Interface Sliver
        - For L2 services, validate the VLAN tag specified is within the allowed range
        - For L3 services,
            - grab the VLAN from BQM Site specific NetworkService
            - exclude the VLAN already assigned to other Interface Sliver on the same port
            - allocate the first available VLAN to the Interface Sliver
        :param requested_ns: Requested NetworkService
        :param requested_ifs: Requested Interface Sliver
        :param owner_switch: BQM Owner site switch identified to serve the InterfaceSliver
        :param mpls_ns: BQM MPLS NetworkService identified to serve the InterfaceSliver
        :param bqm_ifs_id: BQM InterfaceSliver identified to serve the InterfaceSliver
        :param existing_reservations: Existing Reservations which also are served by the owner switch
        :return Interface Sliver updated with the allocated VLAN tag for FABNetv4 and FABNetv6 services
        :raises Exception if vlan tag range is not in the valid range for L2 services
        Return the sliver updated with the VLAN
        """
        if requested_ns.get_layer() == NSLayer.L2:
            delegation_id, delegated_label = self._get_delegations(
                lab_cap_delegations=mpls_ns.get_label_delegations())
            vlans = None
            if delegated_label.vlan_range is not None:
                vlans = delegated_label.vlan_range.split("-")
            if vlans is not None and requested_ifs.labels.vlan is not None and \
                    int(vlans[0]) > int(requested_ifs.labels.vlan) > int(vlans[1]):
                raise BrokerException(
                    error_code=ExceptionErrorCode.FAILURE,
                    msg=f"Vlan for L2 service is outside the allowed range "
                    f"{mpls_ns.label_delegations.vlan_range}")

        else:
            for ns in owner_switch.network_service_info.network_services.values(
            ):
                if requested_ns.get_type() == ns.get_type():
                    # Grab Label Delegations
                    delegation_id, delegated_label = self._get_delegations(
                        lab_cap_delegations=ns.get_label_delegations())

                    # Get the VLAN range
                    vlans = None
                    vlan_range = None
                    if delegated_label.vlan_range is not None:
                        vlans = delegated_label.vlan_range.split("-")
                        vlan_range = list(range(int(vlans[0]), int(vlans[1])))

                    # Exclude the already allocated VLANs and subnets
                    if existing_reservations is not None:
                        for reservation in existing_reservations:
                            # For Active or Ticketed or Ticketing reservations; reduce the counts from available
                            allocated_sliver = None
                            if reservation.is_ticketing(
                            ) and reservation.get_approved_resources(
                            ) is not None:
                                allocated_sliver = reservation.get_approved_resources(
                                ).get_sliver()

                            if (reservation.is_active() or reservation.is_ticketed()) and \
                                    reservation.get_resources() is not None:
                                allocated_sliver = reservation.get_resources(
                                ).get_sliver()

                            self.logger.debug(
                                f"Existing res# {reservation.get_reservation_id()} allocated: {allocated_sliver}"
                            )

                            if allocated_sliver is None:
                                continue

                            # Ignore reservations for L2 services
                            if allocated_sliver.get_type() != ServiceType.FABNetv4 or \
                                    allocated_sliver.get_type() != ServiceType.FABNetv6:
                                continue

                            if allocated_sliver.interface_info is None or allocated_sliver.interface_info.interfaces is None:
                                continue

                            for allocated_ifs in allocated_sliver.interface_info.interfaces.values(
                            ):
                                # Ignore the Interface Slivers not on the same port
                                if allocated_ifs.get_node_map(
                                )[0] != bqm_ifs_id:
                                    continue

                                self.logger.debug(
                                    f"Excluding already allocated VLAN: "
                                    f"{allocated_ifs.label_allocations.vlan} to "
                                    f"res# {reservation.get_reservation_id()}")

                                # Exclude VLANs on the allocated on the same port
                                if vlan_range is not None and allocated_ifs.label_allocations.vlan in vlan_range:
                                    vlan_range.remove(
                                        int(allocated_sliver.label_allocations.
                                            vlan))

                    # Allocate the first available VLAN
                    if vlan_range is not None:
                        requested_ifs.labels.vlan = str(vlan_range[0])
                        requested_ifs.label_allocations = Labels(
                            vlan=str(vlan_range[0]))
                    break
        return requested_ifs