Beispiel #1
0
    def build_slice_with_compute_only(include_components: bool = False, exceed_capacities: bool = False,
                                      exceed_components: bool = False, use_hints: bool = False, no_cap: bool = False,
                                      instance_type: str = "fabric.c8.m32.d500") -> str:
        t = fu.ExperimentTopology()
        n1 = t.add_node(name='n1', site='RENC')

        n1.set_properties(image_type='qcow2', image_ref='default_centos_8')

        n2 = t.add_node(name='n2', site='RENC')
        n2.set_properties(image_type='qcow2', image_ref='default_centos_8')

        if not no_cap:
            cap = None
            if exceed_capacities:
                cap = fu.Capacities(core=33, ram=64, disk=500)
            else:
                cap = fu.Capacities(core=3, ram=61, disk=499)
            n1.set_properties(capacities=cap)
            n2.set_properties(capacities=cap)

        if include_components:
            n1.add_component(ctype=fu.ComponentType.SmartNIC, model='ConnectX-6', name='nic1')
            n2.add_component(ctype=fu.ComponentType.NVME, model='P4510', name='c1')
            n2.add_component(ctype=fu.ComponentType.GPU, model='RTX6000', name='c2')
            if exceed_components:
                n2.add_component(ctype=fu.ComponentType.GPU, model='Tesla T4', name='c3')
                n2.add_component(ctype=fu.ComponentType.SmartNIC, model='ConnectX-6', name='nic1')
                n2.add_component(ctype=fu.ComponentType.SmartNIC, model='ConnectX-5', name='nic2')

        if use_hints:
            cap_hints = fu.CapacityHints(instance_type=instance_type)
            n1.set_properties(capacity_hints=cap_hints)
            n2.set_properties(capacity_hints=cap_hints)

        return t.serialize()
Beispiel #2
0
    def testSerDes3(self):
        # multi-format serialization-deserialization test
        topo = f.ExperimentTopology()
        topo.add_node(name='n1', site='RENC')
        cap = f.Capacities(core=1, unit=2)
        topo.nodes['n1'].capacities = cap
        topo.nodes['n1'].add_component(ctype=f.ComponentType.SharedNIC,
                                       model='ConnectX-6',
                                       name='nic1')
        topo.add_node(name='n2', site='UKY')
        topo.nodes['n2'].add_component(ctype=f.ComponentType.SharedNIC,
                                       model='ConnectX-6',
                                       name='nic2')
        topo.add_network_service(name='s1',
                                 nstype=f.ServiceType.L2STS,
                                 interfaces=topo.interface_list)
        slice_graph = topo.serialize(fmt=f.GraphFormat.JSON_NODELINK)

        print(f'NODE_LINK {slice_graph=}')

        t1 = f.ExperimentTopology(graph_string=slice_graph)

        self.assertTrue('n1' in t1.nodes.keys())
        self.assertTrue('nic1' in t1.nodes['n1'].components.keys())
        cap1 = t1.nodes['n1'].capacities
        self.assertEqual(cap1.core, 1)
        self.assertEqual(cap1.unit, 2)

        print(f'LIST COMPONENTS of n1 {t1.nodes["n1"].components}')
        print(f'LIST COMPONENTS of n2 {t1.nodes["n2"].components}')
        self.n4j_imp.delete_all_graphs()
Beispiel #3
0
    def test_asm_transfer(self):
        """
        Test creating ASM in NetworkX and transition to Neo4j
        :return:
        """
        t = fu.ExperimentTopology()
        n1 = t.add_node(name='n1', site='RENC')
        cap = fu.Capacities(core=4, ram=64, disk=500)
        n1.set_properties(capacities=cap,
                          image_type='qcow2',
                          image_ref='default_centos_8')
        n1.add_component(ctype=fu.ComponentType.SmartNIC,
                         model='ConnectX-6',
                         name='nic1')
        n2 = t.add_node(name='n2', site='RENC')
        n2.set_properties(capacities=cap,
                          image_type='qcow2',
                          image_ref='default_centos_8')
        n2.add_component(ctype=fu.ComponentType.GPU,
                         model='RTX6000',
                         name='nic2')
        slice_graph = t.serialize()

        #t.serialize(file_name='slice_graph.graphml')
        generic_graph = self.n4j_imp.import_graph_from_string(
            graph_string=slice_graph, graph_id=t.graph_model.graph_id)
        asm_graph = Neo4jASMFactory.create(generic_graph)
        node_ids = asm_graph.list_all_node_ids()
        print('ASM Node IDs')
        print(node_ids)
        node_id = next(iter(node_ids))

        # this is how you map  to BQM
        asm_graph.set_mapping(node_id=node_id,
                              to_graph_id="dead-beef",
                              to_node_id='beef-beef')
        to_graph, to_node = asm_graph.get_mapping(node_id=node_id)

        assert (to_graph == "dead-beef")
        assert (to_node == "beef-beef")

        # test creating an experiment topology as a cast of an ASM loaded into Neo4j
        neo4j_topo = fu.ExperimentTopology()
        neo4j_topo.cast(asm_graph=asm_graph)

        print(f'New topology on top of {neo4j_topo.graph_model.graph_id}')
        print(neo4j_topo.nodes)

        # set allocated capacities or labels
        # in orchestrator
        alloc_labels = fu.Labels(instance_parent="worker_node-1")
        neo4j_topo.nodes['n1'].set_properties(label_allocations=alloc_labels)
        # in AM
        provisioned_labels = fu.Labels(instance="open-stack-instance-id-123")
        neo4j_topo.nodes['n1'].set_properties(labels=provisioned_labels)
        ri = fu.ReservationInfo(reservation_id="01234",
                                reservation_state='READY')
        neo4j_topo.nodes['n1'].set_properties(reservation_info=ri)

        self.n4j_imp.delete_all_graphs()
Beispiel #4
0
    def testSerDes2(self):
        # more thorough serialization-deserialization test
        topo = f.ExperimentTopology()
        topo.add_node(name='n1', site='RENC')
        cap = f.Capacities(core=1, unit=2)
        topo.nodes['n1'].capacities = cap
        topo.nodes['n1'].add_component(ctype=f.ComponentType.SharedNIC,
                                       model='ConnectX-6',
                                       name='nic1')
        topo.add_node(name='n2', site='UKY')
        topo.nodes['n2'].add_component(ctype=f.ComponentType.SharedNIC,
                                       model='ConnectX-6',
                                       name='nic2')
        topo.add_network_service(name='s1',
                                 nstype=f.ServiceType.L2STS,
                                 interfaces=topo.interface_list)
        slice_graph = topo.serialize()
        print('\n\n\nINITIAL TOPO')
        print(topo)

        # Import it in the neo4j as ASM
        generic_graph = self.n4j_imp.import_graph_from_string(
            graph_string=slice_graph)
        asm_graph = Neo4jASMFactory.create(generic_graph)

        # Serialize ASM
        orch_graph = asm_graph.serialize_graph()

        # Reload Experiment topology from serialized ASM
        t1 = f.ExperimentTopology(graph_string=orch_graph)

        print('\n\n\nRELOADED TOPO')
        print(t1)
        self.assertTrue('n1' in t1.nodes.keys())
        self.assertTrue('nic1' in t1.nodes['n1'].components.keys())
        cap1 = t1.nodes['n1'].capacities
        self.assertEqual(cap1.core, 1)
        self.assertEqual(cap1.unit, 2)

        print(f'LIST COMPONENTS of n1 {t1.nodes["n1"].components}')
        print(f'LIST COMPONENTS of n2 {t1.nodes["n2"].components}')
        self.n4j_imp.delete_all_graphs()
Beispiel #5
0
    def build_2_site_ptp_slice_sriov() -> str:
        """
        2-site for PTP service between two shared card ports
        """
        t = fu.ExperimentTopology()
        n1 = t.add_node(name='n1', site='RENC', ntype=fu.NodeType.VM)
        n2 = t.add_node(name='n2', site='UKY')

        cap = fu.Capacities(core=2, ram=8, disk=100)
        n1.set_properties(capacities=cap, image_type='qcow2', image_ref='default_centos_8')
        n2.set_properties(capacities=cap, image_type='qcow2', image_ref='default_centos_8')

        n1.add_component(model_type=fu.ComponentModelType.SharedNIC_ConnectX_6, name='n1-nic1')
        n2.add_component(model_type=fu.ComponentModelType.SharedNIC_ConnectX_6, name='n2-nic1')
        n2.add_component(ctype=fu.ComponentType.NVME, model='P4510', name='c1')

        t.add_network_service(name='ptp1', nstype=fu.ServiceType.L2PTP,
                              interfaces=[n1.interface_list[0], n2.interface_list[0]])

        return t.serialize()
Beispiel #6
0
    def build_slice() -> str:
        t = fu.ExperimentTopology()
        n1 = t.add_node(name='n1', site='RENC', ntype=fu.NodeType.VM)
        n2 = t.add_node(name='n2', site='RENC')
        n3 = t.add_node(name='n3', site='RENC')

        cap = fu.Capacities(core=2, ram=8, disk=100)
        n1.set_properties(capacities=cap, image_type='qcow2', image_ref='default_centos_8')
        n2.set_properties(capacities=cap, image_type='qcow2', image_ref='default_centos_8')
        n3.set_properties(capacities=cap, image_type='qcow2', image_ref='default_centos_8')

        n1.add_component(model_type=fu.ComponentModelType.SharedNIC_ConnectX_6, name='n1-nic1')

        n2.add_component(model_type=fu.ComponentModelType.SmartNIC_ConnectX_6, name='n2-nic1')
        n2.add_component(ctype=fu.ComponentType.NVME, model='P4510', name='c1')

        n3.add_component(model_type=fu.ComponentModelType.SmartNIC_ConnectX_5, name='n3-nic1')

        t.add_network_service(name='bridge1', nstype=fu.ServiceType.L2Bridge, interfaces=t.interface_list)

        return t.serialize()
    def testNodeAndServiceSlivers(self):
        t = f.ExperimentTopology()
        t.add_node(name='n1', site='RENC')
        t.nodes['n1'].capacities = f.Capacities(core=1)
        t.nodes['n1'].add_component(name='c1',
                                    ctype=f.ComponentType.SmartNIC,
                                    model='ConnectX-6')
        d = ABCPropertyGraph.sliver_to_dict(t.nodes['n1'].get_sliver())
        t.add_node(name='n2', site='RENC')
        t.nodes['n2'].add_component(name='c2',
                                    ctype=f.ComponentType.SmartNIC,
                                    model='ConnectX-6')
        t.nodes['n2'].add_component(name='c3',
                                    ctype=f.ComponentType.NVME,
                                    model='P4510')
        t.add_network_service(name='s1',
                              nstype=f.ServiceType.L2Bridge,
                              interfaces=t.interface_list)
        jns = JSONSliver.sliver_to_json(t.nodes['n1'].get_sliver())
        ns1 = JSONSliver.node_sliver_from_json(jns)
        jns = JSONSliver.sliver_to_json(t.nodes['n2'].get_sliver())
        ns2 = JSONSliver.node_sliver_from_json(jns)
        ness = JSONSliver.sliver_to_json(t.network_services['s1'].get_sliver())
        nss1 = JSONSliver.network_service_sliver_from_json(ness)

        self.assertEqual(ns1.capacities.core, 1)
        self.assertEqual(len(ns1.attached_components_info.list_devices()), 1)
        self.assertEqual(len(ns2.attached_components_info.list_devices()), 2)
        self.assertEqual(len(nss1.interface_info.list_interfaces()), 4)
        inames = [
            i.resource_name for i in nss1.interface_info.list_interfaces()
        ]
        self.assertTrue('n2-c2-p1' in inames)
        self.assertEqual(
            ns1.attached_components_info.list_devices()
            [0].network_service_info.list_services()
            [0].interface_info.list_interfaces()[0].capacities.bw, 100)
Beispiel #8
0
    def testNetworkServices(self):
        n1 = self.topo.add_node(name='Node1', site='RENC')
        n2 = self.topo.add_node(name='Node2',
                                site='UKY',
                                ntype=f.NodeType.Server)
        n3 = self.topo.add_node(name='Node3',
                                site='RENC',
                                management_ip='123.45.67.98',
                                image_ref='http://some.image',
                                image_type='image type')

        # component checks
        n1.add_component(ctype=f.ComponentType.GPU,
                         model='RTX6000',
                         name='gpu1')
        n1.add_component(model_type=f.ComponentModelType.SharedNIC_ConnectX_6,
                         name='nic1')
        n1.add_component(model_type=f.ComponentModelType.SmartNIC_ConnectX_6,
                         name='nic4')
        n2.add_component(ctype=f.ComponentType.SmartNIC,
                         model='ConnectX-6',
                         name='nic2')
        nc3 = n3.add_component(ctype=f.ComponentType.SharedNIC,
                               model='ConnectX-6',
                               name='nic3',
                               boot_script='#!/bin/bash echo *')

        #tags on model elements (nodes, links, components, interfaces, network services)
        n1.tags = f.Tags('blue', 'heavy')
        self.assertTrue('blue' in n1.tags)
        # unset the tags
        n1.tags = None
        self.assertEqual(n1.tags, None)

        # flags on model elements
        n1.flags = f.Flags(auto_config=True)
        self.assertTrue(n1.flags.auto_config)
        n1.flags = None
        self.assertEqual(n1.flags, None)

        self.assertEqual(nc3.boot_script, '#!/bin/bash echo *')

        #boot script on nodes only
        n1.boot_script = """
        #!/bin/bash
        
        echo *
        """
        self.assertTrue("bash" in n1.boot_script)
        n1.boot_script = None
        self.assertIsNone(n1.boot_script)

        # measurement data on model elements (nodes, links, components, interfaces, network services)
        # can be set simply as json string (string length not to exceed 1M)
        n1.mf_data = json.dumps(
            {'k1': ['some', 'measurement', 'configuration']})
        # you are guaranteed that whatever is on mf_data is JSON parsable and can be reconstituted into
        # an object
        mf_object1 = n1.mf_data
        self.assertTrue(
            mf_object1['k1'] == ['some', 'measurement', 'configuration'])
        # when nothing is set, it is None
        self.assertEqual(n2.mf_data, None)

        # you can also set it as MeasurementData object
        my_meas_data_object = {'key1': {'key2': ['v1', 2]}}
        n1.mf_data = f.MeasurementData(json.dumps(my_meas_data_object))

        # you can also just pass a JSON serializable object to MeasurementData constructor:
        n1.mf_data = f.MeasurementData(my_meas_data_object)
        # or even an serializable object itself. Either way the limit of 1M on the JSON string
        # length is enforced
        n1.mf_data = my_meas_data_object

        # for most uses, just set the object
        my_meas_data_object = {'key1': {'key2': ['some', 'config', 'info']}}
        n1.mf_data = my_meas_data_object

        # you get back your object (in this case a dict)
        self.assertTrue(isinstance(n1.mf_data, dict))
        mf_object2 = n1.mf_data
        self.assertTrue(
            mf_object2['key1'] == {'key2': ['some', 'config', 'info']})

        class MyClass:
            def __init__(self, val):
                self.val = val

        # this is not a valid object - json.dumps() will fail on it
        bad_meas_data_object = {'key1': MyClass(3)}
        with self.assertRaises(MeasurementDataError):
            n1.mf_data = bad_meas_data_object

        # also cannot use bad strings
        with self.assertRaises(MeasurementDataError):
            # you cannot assign non-json string to measurement data either as MeasurementData object
            n1.mf_data = f.MeasurementData("not parsable json")
        with self.assertRaises(MeasurementDataError):
            # or directly as string
            n1.mf_data = 'random string'

        # most settable properties can be unset by setting them to None (there are exceptions, like e.g. name)
        n1.mf_data = None
        self.assertIsNone(n1.mf_data)

        gpu1 = n1.components['gpu1']
        nic1 = n1.components['nic1']
        nic2 = n2.components['nic2']

        p1 = nic2.interfaces['nic2-p1']
        p2 = nic2.interfaces['nic2-p2']

        cap = f.Capacities(bw=50, unit=1)
        nic1.capacities = cap
        lab = f.Labels(ipv4="192.168.1.12")
        nic1.labels = lab
        caphints = f.CapacityHints(instance_type='blah')
        n1.capacity_hints = caphints

        # check capacities, hints labels on the graph
        n1p = self.topo.nodes['Node1']
        caphints1 = n1p.get_property('capacity_hints')
        assert (caphints.instance_type == caphints1.instance_type)
        caphints1 = n1p.capacity_hints
        assert (caphints.instance_type == caphints1.instance_type)

        #s1 = self.topo.add_network_service(name='s1', nstype=f.ServiceType.L2Bridge, interfaces=self.topo.interface_list)

        s1 = self.topo.add_network_service(name='s1',
                                           nstype=f.ServiceType.L2STS,
                                           interfaces=[
                                               n1.interface_list[0],
                                               n2.interface_list[0],
                                               n3.interface_list[0]
                                           ])

        # facilities
        fac1 = self.topo.add_facility(name='RENCI-DTN',
                                      site='RENC',
                                      capacities=f.Capacities(bw=10),
                                      labels=f.Labels(vlan='100'))
        # facility needs to be connected via a service to something else
        sfac = self.topo.add_network_service(
            name='s-fac',
            nstype=f.ServiceType.L2STS,
            interfaces=[fac1.interface_list[0], n1.interface_list[2]])

        self.assertEqual(s1.layer, f.Layer.L2)
        print(fac1.network_services['RENCI-DTN-ns'].labels)
        self.assertEqual(fac1.network_services['RENCI-DTN-ns'].layer,
                         f.Layer.L2)
        self.assertEqual(fac1.interface_list[0].labels.vlan, '100')

        # this is typically done by orchestrator
        s1.gateway = Gateway(
            Labels(ipv4_subnet="192.168.1.0/24",
                   ipv4="192.168.1.1",
                   mac="00:11:22:33:44:55"))

        self.assertEqual(s1.gateway.gateway, "192.168.1.1")
        self.assertEqual(s1.gateway.subnet, "192.168.1.0/24")

        print(f'S1 has these interfaces: {s1.interface_list}')
        self.assertEqual(len(s1.interface_list), 3)
        self.topo.validate()

        # Import it in the neo4j as ASM
        slice_graph = self.topo.serialize()
        generic_graph = self.n4j_imp.import_graph_from_string(
            graph_string=slice_graph)
        asm_graph = Neo4jASMFactory.create(generic_graph)
        asm_graph.validate_graph()
        self.n4j_imp.delete_all_graphs()

        s1p = self.topo.network_services['s1']

        print(f'S1 has these interfaces: {s1p.interface_list}')

        s1.disconnect_interface(interface=p1)

        print(f'S1 has these interfaces: {s1.interface_list}')
        self.assertEqual(len(s1.interface_list), 2)

        # validate the topology
        self.topo.validate()

        # Import it in the neo4j as ASM
        generic_graph = self.n4j_imp.import_graph_from_string(
            graph_string=slice_graph)
        asm_graph = Neo4jASMFactory.create(generic_graph)
        asm_graph.validate_graph()
        self.n4j_imp.delete_all_graphs()

        self.topo.remove_network_service('s1')

        with self.assertRaises(TopologyException):
            # connection conflict because we have an interface connecting to s-fac
            s2 = self.topo.add_network_service(
                name='s2',
                nstype=f.ServiceType.L2PTP,
                interfaces=self.topo.interface_list)

        s2 = self.topo.add_network_service(
            name='s2',
            nstype=f.ServiceType.L2PTP,
            interfaces=[n1.interface_list[1], n2.interface_list[1]])
        self.assertEqual(len(s2.interface_list), 2)
        print(f'S2 has these interfaces: {s2.interface_list}')

        print(f'There are {self.topo.links}  links left in topology')
        self.assertEqual(len(self.topo.links), 4)
        print(
            f'There are {self.topo.network_services} Network services  in topology'
        )
        self.assertEqual(len(self.topo.network_services), 7)
        self.topo.validate()
        self.topo.remove_network_service('s2')
        self.topo.validate()
        self.assertEqual(len(self.topo.network_services), 6)
        n1.remove_component('nic1')
        self.assertEqual(len(self.topo.network_services), 5)