Commit a742df66 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'fix/ci-cd-pipeline' into 'develop'

Fix CI/CD pipeline

See merge request !78
parents 741d929b 8766c63b
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -222,13 +222,13 @@ class DescriptorLoader:
        self.__topologies_add = get_descriptors_add_topologies(self.__topologies)

        if self.__dummy_mode:
            self._dummy_mode()
            self._load_dummy_mode()
        else:
            self._normal_mode()
            self._load_normal_mode()
        
        return self.__results

    def _dummy_mode(self) -> None:
    def _load_dummy_mode(self) -> None:
        # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
        self.__ctx_cli.connect()
        self._process_descr('context',    'add',    self.__ctx_cli.SetContext,    Context,    self.__contexts_add  )
@@ -242,7 +242,7 @@ class DescriptorLoader:
        self._process_descr('topology',   'update', self.__ctx_cli.SetTopology,   Topology,   self.__topologies    )
        #self.__ctx_cli.close()

    def _normal_mode(self) -> None:
    def _load_normal_mode(self) -> None:
        # Normal mode: follows the automated workflows in the different components
        assert len(self.__connections) == 0, 'in normal mode, connections should not be set'

@@ -321,7 +321,35 @@ class DescriptorLoader:
            response = self.__ctx_cli.ListSlices(ContextId(**json_context_id(context_uuid)))
            assert len(response.slices) == num_slices

    def unload(self) -> None:
    def _unload_dummy_mode(self) -> None:
        # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
        self.__ctx_cli.connect()

        for _, slice_list in self.slices.items():
            for slice_ in slice_list:
                self.__ctx_cli.RemoveSlice(SliceId(**slice_['slice_id']))

        for _, service_list in self.services.items():
            for service in service_list:
                self.__ctx_cli.RemoveService(ServiceId(**service['service_id']))

        for link in self.links:
            self.__ctx_cli.RemoveLink(LinkId(**link['link_id']))

        for device in self.devices:
            self.__ctx_cli.RemoveDevice(DeviceId(**device['device_id']))

        for _, topology_list in self.topologies.items():
            for topology in topology_list:
                self.__ctx_cli.RemoveTopology(TopologyId(**topology['topology_id']))

        for context in self.contexts:
            self.__ctx_cli.RemoveContext(ContextId(**context['context_id']))

        #self.__ctx_cli.close()

    def _unload_normal_mode(self) -> None:
        # Normal mode: follows the automated workflows in the different components
        self.__ctx_cli.connect()
        self.__dev_cli.connect()
        self.__svc_cli.connect()
@@ -348,6 +376,17 @@ class DescriptorLoader:
        for context in self.contexts:
            self.__ctx_cli.RemoveContext(ContextId(**context['context_id']))

        #self.__ctx_cli.close()
        #self.__dev_cli.close()
        #self.__svc_cli.close()
        #self.__slc_cli.close()

    def unload(self) -> None:
        if self.__dummy_mode:
            self._unload_dummy_mode()
        else:
            self._unload_normal_mode()

def compose_notifications(results : TypeResults) -> TypeNotificationList:
    notifications = []
    for entity_name, action_name, num_ok, error_list in results:
+8 −2
Original line number Diff line number Diff line
@@ -62,8 +62,14 @@ RUN python3 -m pip install -r requirements.txt

# Add component files into working directory
WORKDIR /var/teraflow
COPY src/context/. context/
COPY src/device/. device/
COPY src/context/__init__.py context/__init__.py
COPY src/context/client/. context/client/
COPY src/device/__init__.py device/__init__.py
COPY src/device/client/. device/client/
COPY src/service/__init__.py service/__init__.py
COPY src/service/client/. service/client/
COPY src/slice/__init__.py slice/__init__.py
COPY src/slice/client/. slice/client/
COPY src/pathcomp/. pathcomp/

# Start the service
+21 −64
Original line number Diff line number Diff line
@@ -14,12 +14,10 @@

import operator
from typing import Dict, List, Optional, Set, Tuple
from common.proto.context_pb2 import Connection, Link, Service
from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompReply, PathCompRequest
from common.proto.context_pb2 import Link
from common.proto.pathcomp_pb2 import Algorithm_KDisjointPath, Algorithm_KShortestPath, PathCompRequest
from common.tools.grpc.Tools import grpc_message_to_json_string
from pathcomp.frontend.service.algorithms.tools.ComputeSubServices import convert_explicit_path_hops_to_connections
from pathcomp.frontend.service.algorithms.tools.EroPathToHops import eropath_to_hops
from ._Algorithm import _Algorithm
from ._Algorithm import _Algorithm, SRC_END
from .KShortestPathAlgorithm import KShortestPathAlgorithm

Service_Id          = Tuple[str, str]   # (context_uuid, service_uuid)
@@ -100,7 +98,7 @@ class KDisjointPathAlgorithm(_Algorithm):
    def get_link_from_endpoint(self, endpoint : Dict) -> Tuple[Dict, Link]:
        device_uuid = endpoint['device_id']
        endpoint_uuid = endpoint['endpoint_uuid']
        item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid))
        item = self.endpoint_to_link_dict.get((device_uuid, endpoint_uuid, SRC_END))
        if item is None:
            MSG = 'Link for Endpoint({:s}, {:s}) not found'
            self.logger.warning(MSG.format(device_uuid, endpoint_uuid))
@@ -141,7 +139,7 @@ class KDisjointPathAlgorithm(_Algorithm):

        Path = List[Dict]
        Path_NoPath = Optional[Path] # None = no path, list = path
        self.json_reply : Dict[Tuple[str, str], List[Path_NoPath]] = dict()
        service_to_paths : Dict[Tuple[str, str], List[Path_NoPath]] = dict()

        for num_path in range(self.num_disjoint):
            algorithm.service_list = list()
@@ -189,66 +187,25 @@ class KDisjointPathAlgorithm(_Algorithm):
            for response in response_list:
                service_id = response['serviceId']
                service_key = (service_id['contextId'], service_id['service_uuid'])
                json_reply_service = self.json_reply.setdefault(service_key, list())
                json_reply_service = service_to_paths.setdefault(service_key, list())

                no_path_issue = response.get('noPath', {}).get('issue')
                if no_path_issue is not None:
                    json_reply_service.append(None)
                    continue
                if no_path_issue is not None: continue

                path_endpoints = response['path'][0]['devices']
                path_endpoints = response['path'][0]
                json_reply_service.append(path_endpoints)
                algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints)
                algorithm.link_list = self.remove_traversed_links(algorithm.link_list, path_endpoints['devices'])

        self.json_reply = dict()
        response_list = self.json_reply.setdefault('response-list', [])
        for service_key,paths in service_to_paths.items():
            response = {'serviceId': {
                'contextId': service_key[0],
                'service_uuid': service_key[1],
            }}
            response['path'] = paths
            if len(paths) < self.num_disjoint:
                response['noPath'] = {'issue': 1}
            response_list.append(response)

        self.logger.debug('self.json_reply = {:s}'.format(str(self.json_reply)))

    def get_reply(self) -> PathCompReply:
        reply = PathCompReply()
        grpc_services : Dict[Tuple[str, str], Service] = {}
        grpc_connections : Dict[Tuple[int, str], Connection] = {}
        for service_key,paths in self.json_reply.items():
            context_uuid, service_uuid = service_key

            grpc_services[service_key] = self.add_service_to_reply(reply, context_uuid, service_uuid)

            for num_path,service_path_ero in enumerate(paths):
                self.logger.warning('num_path={:d}'.format(num_path))
                self.logger.warning('service_path_ero={:s}'.format(str(service_path_ero)))
                if service_path_ero is None: continue
                path_hops = eropath_to_hops(service_path_ero, self.endpoint_to_link_dict)
                self.logger.warning('path_hops={:s}'.format(str(path_hops)))
                connections = convert_explicit_path_hops_to_connections(path_hops, self.device_dict, service_uuid)
                self.logger.warning('connections={:s}'.format(str(connections)))

                for connection in connections:
                    connection_uuid,device_layer,path_hops,_ = connection

                    service_key = (context_uuid, connection_uuid)
                    grpc_service = grpc_services.get(service_key)
                    if grpc_service is not None: continue
                    grpc_service = self.add_service_to_reply(
                        reply, context_uuid, connection_uuid, device_layer=device_layer, path_hops=path_hops)
                    grpc_services[service_key] = grpc_service

                for connection in connections:
                    connection_uuid,device_layer,path_hops,dependencies = connection

                    service_key = (context_uuid, connection_uuid)
                    grpc_service = grpc_services.get(service_key)
                    if grpc_service is None: raise Exception('Service({:s}) not found'.format(str(service_key)))

                    connection_uuid = '{:s}:{:d}'.format(connection_uuid, num_path)
                    grpc_connection = grpc_connections.get(connection_uuid)
                    if grpc_connection is not None: continue
                    grpc_connection = self.add_connection_to_reply(reply, connection_uuid, grpc_service, path_hops)
                    grpc_connections[connection_uuid] = grpc_connection

                    for sub_service_uuid in dependencies:
                        sub_service_key = (context_uuid, sub_service_uuid)
                        grpc_sub_service = grpc_services.get(sub_service_key)
                        if grpc_sub_service is None:
                            raise Exception('Service({:s}) not found'.format(str(sub_service_key)))
                        grpc_sub_service_id = grpc_connection.sub_service_ids.add()
                        grpc_sub_service_id.CopyFrom(grpc_sub_service.service_id)

        return reply
+46 −24
Original line number Diff line number Diff line
@@ -80,21 +80,36 @@ DEVICE_C3_ID, DEVICE_C3_ENDPOINTS, DEVICE_C3 = compose_device('C3', ['1', '2', '
LINK_A2_C3_ID, LINK_A2_C3 = compose_link(DEVICE_A2_ENDPOINTS[2], DEVICE_C3_ENDPOINTS[2])
LINK_C1_B2_ID, LINK_C1_B2 = compose_link(DEVICE_C1_ENDPOINTS[2], DEVICE_B2_ENDPOINTS[2])

LINK_C3_A2_ID, LINK_C3_A2 = compose_link(DEVICE_C3_ENDPOINTS[2], DEVICE_A2_ENDPOINTS[2])
LINK_B2_C1_ID, LINK_B2_C1 = compose_link(DEVICE_B2_ENDPOINTS[2], DEVICE_C1_ENDPOINTS[2])

# ----- IntraDomain A Links --------------------------------------------------------------------------------------------
LINK_A1_A2_ID, LINK_A1_A2 = compose_link(DEVICE_A1_ENDPOINTS[0], DEVICE_A2_ENDPOINTS[0])
LINK_A1_A3_ID, LINK_A1_A3 = compose_link(DEVICE_A1_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[0])
LINK_A2_A3_ID, LINK_A2_A3 = compose_link(DEVICE_A2_ENDPOINTS[1], DEVICE_A3_ENDPOINTS[1])

LINK_A2_A1_ID, LINK_A2_A1 = compose_link(DEVICE_A2_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[0])
LINK_A3_A1_ID, LINK_A3_A1 = compose_link(DEVICE_A3_ENDPOINTS[0], DEVICE_A1_ENDPOINTS[1])
LINK_A3_A2_ID, LINK_A3_A2 = compose_link(DEVICE_A3_ENDPOINTS[1], DEVICE_A2_ENDPOINTS[1])

# ----- IntraDomain B Links --------------------------------------------------------------------------------------------
LINK_B1_B2_ID, LINK_B1_B2 = compose_link(DEVICE_B1_ENDPOINTS[0], DEVICE_B2_ENDPOINTS[0])
LINK_B1_B3_ID, LINK_B1_B3 = compose_link(DEVICE_B1_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[0])
LINK_B2_B3_ID, LINK_B2_B3 = compose_link(DEVICE_B2_ENDPOINTS[1], DEVICE_B3_ENDPOINTS[1])

LINK_B2_B1_ID, LINK_B2_B1 = compose_link(DEVICE_B2_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[0])
LINK_B3_B1_ID, LINK_B3_B1 = compose_link(DEVICE_B3_ENDPOINTS[0], DEVICE_B1_ENDPOINTS[1])
LINK_B3_B2_ID, LINK_B3_B2 = compose_link(DEVICE_B3_ENDPOINTS[1], DEVICE_B2_ENDPOINTS[1])

# ----- IntraDomain C Links --------------------------------------------------------------------------------------------
LINK_C1_C2_ID, LINK_C1_C2 = compose_link(DEVICE_C1_ENDPOINTS[0], DEVICE_C2_ENDPOINTS[0])
LINK_C1_C3_ID, LINK_C1_C3 = compose_link(DEVICE_C1_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[0])
LINK_C2_C3_ID, LINK_C2_C3 = compose_link(DEVICE_C2_ENDPOINTS[1], DEVICE_C3_ENDPOINTS[1])

LINK_C2_C1_ID, LINK_C2_C1 = compose_link(DEVICE_C2_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[0])
LINK_C3_C1_ID, LINK_C3_C1 = compose_link(DEVICE_C3_ENDPOINTS[0], DEVICE_C1_ENDPOINTS[1])
LINK_C3_C2_ID, LINK_C3_C2 = compose_link(DEVICE_C3_ENDPOINTS[1], DEVICE_C2_ENDPOINTS[1])

# ----- Service --------------------------------------------------------------------------------------------------------
SERVICE_A1_B1 = compose_service(DEVICE_A1_ENDPOINTS[2], DEVICE_B1_ENDPOINTS[2], constraints=[
    json_constraint_sla_capacity(10.0),
@@ -108,31 +123,38 @@ DEVICES = [ DEVICE_A1, DEVICE_A2, DEVICE_A3,
                DEVICE_B1, DEVICE_B2, DEVICE_B3,
                DEVICE_C1, DEVICE_C2, DEVICE_C3,    ]
LINKS      = [  LINK_A2_C3, LINK_C1_B2,
                LINK_C3_A2, LINK_B2_C1,

                LINK_A1_A2, LINK_A1_A3, LINK_A2_A3,
                LINK_A2_A1, LINK_A3_A1, LINK_A3_A2,

                LINK_B1_B2, LINK_B1_B3, LINK_B2_B3,
                LINK_C1_C2, LINK_C1_C3, LINK_C2_C3, ]
                LINK_B2_B1, LINK_B3_B1, LINK_B3_B2,

                LINK_C1_C2, LINK_C1_C3, LINK_C2_C3,
                LINK_C2_C1, LINK_C3_C1, LINK_C3_C2, ]
SERVICES   = [  SERVICE_A1_B1]

OBJECTS_PER_TOPOLOGY = [
    (TOPOLOGY_ADMIN_ID,
        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,
            DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,
            DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
        [   LINK_A2_C3_ID, LINK_C1_B2_ID,
            LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,
            LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,
            LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
    ),
    (TOPOLOGY_A_ID,
        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,       ],
        [   LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,    ],
    ),
    (TOPOLOGY_B_ID,
        [   DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,       ],
        [   LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,    ],
    ),
    (TOPOLOGY_C_ID,
        [   DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
        [   LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
    ),
]
#OBJECTS_PER_TOPOLOGY = [
#    (TOPOLOGY_ADMIN_ID,
#        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,
#            DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,
#            DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
#        [   LINK_A2_C3_ID, LINK_C1_B2_ID,
#            LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,
#            LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,
#            LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
#    ),
#    (TOPOLOGY_A_ID,
#        [   DEVICE_A1_ID, DEVICE_A2_ID, DEVICE_A3_ID,       ],
#        [   LINK_A1_A2_ID, LINK_A1_A3_ID, LINK_A2_A3_ID,    ],
#    ),
#    (TOPOLOGY_B_ID,
#        [   DEVICE_B1_ID, DEVICE_B2_ID, DEVICE_B3_ID,       ],
#        [   LINK_B1_B2_ID, LINK_B1_B3_ID, LINK_B2_B3_ID,    ],
#    ),
#    (TOPOLOGY_C_ID,
#        [   DEVICE_C1_ID, DEVICE_C2_ID, DEVICE_C3_ID,       ],
#        [   LINK_C1_C2_ID, LINK_C1_C3_ID, LINK_C2_C3_ID,    ],
#    ),
#]
+56 −32
Original line number Diff line number Diff line
@@ -118,6 +118,11 @@ LINK_DC1GW_CS1GW2_ID, LINK_DC1GW_CS1GW2 = compose_link(DEV_DC1GW_EPS[1], DEV_CS1
LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW1 = compose_link(DEV_DC2GW_EPS[0], DEV_CS2GW1_EPS[0])
LINK_DC2GW_CS2GW2_ID, LINK_DC2GW_CS2GW2 = compose_link(DEV_DC2GW_EPS[1], DEV_CS2GW2_EPS[0])

LINK_CS1GW1_DC1GW_ID, LINK_CS1GW1_DC1GW = compose_link(DEV_CS1GW1_EPS[0], DEV_DC1GW_EPS[0])
LINK_CS1GW2_DC1GW_ID, LINK_CS1GW2_DC1GW = compose_link(DEV_CS1GW2_EPS[0], DEV_DC1GW_EPS[1])
LINK_CS2GW1_DC2GW_ID, LINK_CS2GW1_DC2GW = compose_link(DEV_CS2GW1_EPS[0], DEV_DC2GW_EPS[0])
LINK_CS2GW2_DC2GW_ID, LINK_CS2GW2_DC2GW = compose_link(DEV_CS2GW2_EPS[0], DEV_DC2GW_EPS[1])

# InterDomain CSGW-TN
LINK_CS1GW1_TNR1_ID, LINK_CS1GW1_TNR1 = compose_link(DEV_CS1GW1_EPS[1], DEV_TNR1_EPS[0])
LINK_CS1GW2_TNR2_ID, LINK_CS1GW2_TNR2 = compose_link(DEV_CS1GW2_EPS[1], DEV_TNR2_EPS[0])
@@ -128,6 +133,15 @@ LINK_CS2GW2_TNR4_ID, LINK_CS2GW2_TNR4 = compose_link(DEV_CS2GW2_EPS[1], DEV_TNR4
LINK_CS2GW1_TNR4_ID, LINK_CS2GW1_TNR4 = compose_link(DEV_CS2GW1_EPS[2], DEV_TNR4_EPS[1])
LINK_CS2GW2_TNR3_ID, LINK_CS2GW2_TNR3 = compose_link(DEV_CS2GW2_EPS[2], DEV_TNR3_EPS[1])

LINK_TNR1_CS1GW1_ID, LINK_TNR1_CS1GW1 = compose_link(DEV_TNR1_EPS[0], DEV_CS1GW1_EPS[1])
LINK_TNR2_CS1GW2_ID, LINK_TNR2_CS1GW2 = compose_link(DEV_TNR2_EPS[0], DEV_CS1GW2_EPS[1])
LINK_TNR2_CS1GW1_ID, LINK_TNR2_CS1GW1 = compose_link(DEV_TNR2_EPS[1], DEV_CS1GW1_EPS[2])
LINK_TNR1_CS1GW2_ID, LINK_TNR1_CS1GW2 = compose_link(DEV_TNR1_EPS[1], DEV_CS1GW2_EPS[2])
LINK_TNR3_CS2GW1_ID, LINK_TNR3_CS2GW1 = compose_link(DEV_TNR3_EPS[0], DEV_CS2GW1_EPS[1])
LINK_TNR4_CS2GW2_ID, LINK_TNR4_CS2GW2 = compose_link(DEV_TNR4_EPS[0], DEV_CS2GW2_EPS[1])
LINK_TNR4_CS2GW1_ID, LINK_TNR4_CS2GW1 = compose_link(DEV_TNR4_EPS[1], DEV_CS2GW1_EPS[2])
LINK_TNR3_CS2GW2_ID, LINK_TNR3_CS2GW2 = compose_link(DEV_TNR3_EPS[1], DEV_CS2GW2_EPS[2])

# IntraDomain TN
LINK_TNR1_TNR2_ID, LINK_TNR1_TNR2 = compose_link(DEV_TNR1_EPS[2], DEV_TNR2_EPS[3])
LINK_TNR2_TNR3_ID, LINK_TNR2_TNR3 = compose_link(DEV_TNR2_EPS[2], DEV_TNR3_EPS[3])
@@ -136,6 +150,13 @@ LINK_TNR4_TNR1_ID, LINK_TNR4_TNR1 = compose_link(DEV_TNR4_EPS[2], DEV_TNR1_EPS[3
LINK_TNR1_TNR3_ID, LINK_TNR1_TNR3 = compose_link(DEV_TNR1_EPS[4], DEV_TNR3_EPS[4])
LINK_TNR2_TNR4_ID, LINK_TNR2_TNR4 = compose_link(DEV_TNR2_EPS[4], DEV_TNR4_EPS[4])

LINK_TNR2_TNR1_ID, LINK_TNR2_TNR1 = compose_link(DEV_TNR2_EPS[3], DEV_TNR1_EPS[2])
LINK_TNR3_TNR2_ID, LINK_TNR3_TNR2 = compose_link(DEV_TNR3_EPS[3], DEV_TNR2_EPS[2])
LINK_TNR4_TNR3_ID, LINK_TNR4_TNR3 = compose_link(DEV_TNR4_EPS[3], DEV_TNR3_EPS[2])
LINK_TNR1_TNR4_ID, LINK_TNR1_TNR4 = compose_link(DEV_TNR1_EPS[3], DEV_TNR4_EPS[2])
LINK_TNR3_TNR1_ID, LINK_TNR3_TNR1 = compose_link(DEV_TNR3_EPS[4], DEV_TNR1_EPS[4])
LINK_TNR4_TNR2_ID, LINK_TNR4_TNR2 = compose_link(DEV_TNR4_EPS[4], DEV_TNR2_EPS[4])


# ----- Service --------------------------------------------------------------------------------------------------------
SERVICE_DC1GW_DC2GW = compose_service(DEV_DC1GW_EPS[2], DEV_DC2GW_EPS[2], constraints=[
@@ -151,41 +172,44 @@ DEVICES = [ DEV_DC1GW, DEV_DC2GW,
                DEV_TNR1, DEV_TNR2, DEV_TNR3, DEV_TNR4,
            ]
LINKS      = [  LINK_DC1GW_CS1GW1, LINK_DC1GW_CS1GW2, LINK_DC2GW_CS2GW1, LINK_DC2GW_CS2GW2,
                LINK_CS1GW1_DC1GW, LINK_CS1GW2_DC1GW, LINK_CS2GW1_DC2GW, LINK_CS2GW2_DC2GW,

                LINK_CS1GW1_TNR1, LINK_CS1GW2_TNR2, LINK_CS1GW1_TNR2, LINK_CS1GW2_TNR1,
                LINK_CS2GW1_TNR3, LINK_CS2GW2_TNR4, LINK_CS2GW1_TNR4, LINK_CS2GW2_TNR3,
                LINK_TNR1_TNR2, LINK_TNR2_TNR3, LINK_TNR3_TNR4, LINK_TNR4_TNR1, LINK_TNR1_TNR3, LINK_TNR2_TNR4,
                LINK_TNR2_TNR1, LINK_TNR3_TNR2, LINK_TNR4_TNR3, LINK_TNR1_TNR4, LINK_TNR3_TNR1, LINK_TNR4_TNR2,
            ]
SERVICES   = [  SERVICE_DC1GW_DC2GW   ]

OBJECTS_PER_TOPOLOGY = [
    (TOPO_ADMIN_ID,
        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
        ],
        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
            LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
            LINK_TNR2_TNR4_ID,
        ],
    ),
    (TOPO_DC1_ID,
        [DEV_DC1GW_ID],
        []),
    (TOPO_DC2_ID,
        [DEV_DC2GW_ID],
        []),
    (TOPO_CS1_ID,
        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
        []),
    (TOPO_CS2_ID,
        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
        []),
    (TOPO_TN_ID,
        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
        ],
        [   LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
            LINK_TNR2_TNR4_ID,
        ]),
]
#OBJECTS_PER_TOPOLOGY = [
#    (TOPO_ADMIN_ID,
#        [   DEV_DC1GW_ID, DEV_DC2GW_ID,
#            DEV_CS1GW1_ID, DEV_CS1GW2_ID, DEV_CS2GW1_ID, DEV_CS2GW2_ID,
#            DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
#        ],
#        [   LINK_DC1GW_CS1GW1_ID, LINK_DC1GW_CS1GW2_ID, LINK_DC2GW_CS2GW1_ID, LINK_DC2GW_CS2GW2_ID,
#            LINK_CS1GW1_TNR1_ID, LINK_CS1GW2_TNR2_ID, LINK_CS1GW1_TNR2_ID, LINK_CS1GW2_TNR1_ID,
#            LINK_CS2GW1_TNR3_ID, LINK_CS2GW2_TNR4_ID, LINK_CS2GW1_TNR4_ID, LINK_CS2GW2_TNR3_ID,
#            LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
#            LINK_TNR2_TNR4_ID,
#        ],
#    ),
#    (TOPO_DC1_ID,
#        [DEV_DC1GW_ID],
#        []),
#    (TOPO_DC2_ID,
#        [DEV_DC2GW_ID],
#        []),
#    (TOPO_CS1_ID,
#        [DEV_CS1GW1_ID, DEV_CS1GW2_ID],
#        []),
#    (TOPO_CS2_ID,
#        [DEV_CS2GW1_ID, DEV_CS2GW2_ID],
#        []),
#    (TOPO_TN_ID,
#        [   DEV_TNR1_ID, DEV_TNR2_ID, DEV_TNR3_ID, DEV_TNR4_ID,
#        ],
#        [   LINK_TNR1_TNR2_ID, LINK_TNR2_TNR3_ID, LINK_TNR3_TNR4_ID, LINK_TNR4_TNR1_ID, LINK_TNR1_TNR3_ID,
#            LINK_TNR2_TNR4_ID,
#        ]),
#]
Loading