fabric-testbed / InformationModel

FABRIC Information Model library
MIT License
7 stars 1 forks source link

Modify MVP - FIM code that supports diffing topologies #124

Closed ibaldin closed 2 years ago

ibaldin commented 2 years ago

Diffying topologies works.

        diff_res = self.topoA.diff(self.topoB)

where diffres is a TopologyDiff dataclass:

@dataclasses.dataclass
class TopologyDiffTuple:
    nodes: set[Node]
    components: set[Component]
    services: set[NetworkService]
    interfaces: set[Interface]

@dataclasses.dataclass
class TopologyDiff:
    added: TopologyDiffTuple
    removed: TopologyDiffTuple

Note that both topologies (topoA and topoB) must be loaded into Neo4j. Remember that all ModelElement objects (Node, Component, Interface, NetworkService) are shallow and build their innards by querying the underlying backend (Neo4j in this case) when properties are needed. Both graphs topoA and topoB must therefore be present, otherwise only names and GUIDs of the elements will be known.

Creating them can be done thusly:

        self.n4j_imp = Neo4jGraphImporter(url=self.neo4j["url"], user=self.neo4j["user"],
                                          pswd=self.neo4j["pass"],
                                          import_host_dir=self.neo4j["import_host_dir"],
                                          import_dir=self.neo4j["import_dir"])
        self.topoB = f.ExperimentTopology(importer=self.n4j_imp)
        new_id = str(uuid.uuid4())
        # if you need to override graph id use new_graph_id, otherwise parameter is optional
        self.topoB.load(graph_string=graph_A_string, new_graph_id=new_id)

Also now the code allows to dynamically connect/disconnect interfaces from services, not just passing them in the constructor (although that is still valid):

        self.topoA.add_network_service(name='bridge2', nstype=ServiceType.L2Bridge)
        nD = self.topoA.add_node(name='NodeD', site='UKY')
        nic4 = nD.add_component(name='nic4', ctype=ComponentType.SharedNIC, model='ConnectX-6')
        self.topoA.network_services['bridge2'].connect_interface(nic4.interface_list[0])
        nE = self.topoA.add_node(name='NodeE', site='UKY')
        nic5 = nE.add_component(name='nic5', ctype=ComponentType.SharedNIC, model='ConnectX-6')
        self.topoA.network_services['bridge2'].connect_interface(nic5.interface_list[0])

Similarly you can disconnect:

        disconnected_interface = self.topoB.nodes['NodeD'].components['nic4'].interface_list[0]
        self.topoB.network_services['bridge2'].disconnect_interface(disconnected_interface)

Also now substrate models can be validated, not just experiment topology objects.

NOTE: NetworkService objects continue to have site property, however it is no longer set in the constructor (because it may not be possible) by default. Instead the validate() call sets it. Also NetworkService constructor does allow explicitly setting the site property if needed and validate() call checks that it was set correctly based on the interfaces that were connected to the service.

ibaldin commented 2 years ago

This is in PyPi as 1.3.0b2