Loading src/common/tools/descriptor/Loader.py +82 −0 Original line number Diff line number Diff line Loading @@ -40,9 +40,11 @@ from common.proto.context_pb2 import ( Link, LinkId, Service, ServiceId, Slice, SliceId, Topology, TopologyId , OpticalLink ) from common.proto.logical_resources_pb2 import ConfigParameters from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from logical_resources.client.Logicalresourceclient import LogicalResourceClient from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from vnt_manager.client.VNTManagerClient import VNTManagerClient Loading @@ -68,6 +70,7 @@ ENTITY_TO_TEXT = { 'controller': ('Controller', 'Controllers'), 'device' : ('Device', 'Devices' ), 'link' : ('Link', 'Links' ), 'logical_resource': ('Logical Resource', 'Logical Resources'), 'service' : ('Service', 'Services' ), 'slice' : ('Slice', 'Slices' ), 'connection': ('Connection', 'Connections'), Loading Loading @@ -113,6 +116,7 @@ class DescriptorLoader: self, descriptors : Optional[Union[str, Dict]] = None, descriptors_file : Optional[str] = None, num_workers : int = 1, context_client : Optional[ContextClient] = None, device_client : Optional[DeviceClient] = None, logical_resources_client : Optional[LogicalResourceClient] = None, service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None, vntm_client : Optional[VNTManagerClient] = None ) -> None: Loading @@ -136,6 +140,7 @@ class DescriptorLoader: self.__devices = self.__descriptors.get('devices' , []) self.__links = self.__descriptors.get('links' , []) self.__optical_links = self.__descriptors.get('optical_links',[]) self.__logical_resources = self.__descriptors.get('logical_resources', []) self.__services = self.__descriptors.get('services' , []) self.__slices = self.__descriptors.get('slices' , []) self.__ietf_slices = self.__descriptors.get('ietf-network-slice-service:network-slice-services', {}) Loading Loading @@ -194,6 +199,7 @@ class DescriptorLoader: self.__ctx_cli = ContextClient() if context_client is None else context_client self.__dev_cli = DeviceClient() if device_client is None else device_client self.__lrs_cli = LogicalResourceClient() if logical_resources_client is None else logical_resources_client self.__svc_cli = ServiceClient() if service_client is None else service_client self.__slc_cli = SliceClient() if slice_client is None else slice_client self.__vnt_cli = VNTManagerClient() if vntm_client is None else vntm_client Loading Loading @@ -258,6 +264,12 @@ class DescriptorLoader: @property def num_optical_links(self) -> int: return len(self.__optical_links) @property def logical_resources(self) -> List[Dict]: return self.__logical_resources @property def num_logical_resources(self) -> int: return len(self.__logical_resources) @property def services(self) -> Dict[str, List[Dict]]: _services = {} Loading Loading @@ -302,6 +314,8 @@ class DescriptorLoader: self.__services = [format_service_custom_config_rules(service) for service in self.__services] self.__slices = [format_slice_custom_config_rules (slice_ ) for slice_ in self.__slices ] self._process_logical_resources() # Context and Topology require to create the entity first, and add devices, links, services, # slices, etc. in a second stage. self.__contexts_add = get_descriptors_add_contexts(self.__contexts) Loading Loading @@ -403,6 +417,74 @@ class DescriptorLoader: #self.__dev_cli.close() #self.__ctx_cli.close() def _logical_resource_request(self, resource_type: str, allocation: Dict) -> Any: device_uuid = str(allocation.get('device_uuid', '')) endpoint_uuid = str(allocation.get('endpoint_uuid', allocation.get('interface', ''))) device_name = str(allocation.get('device_name', '')) request_kwargs = { 'device_uuid': device_uuid, 'endpoint_uuid': endpoint_uuid, 'name': device_name, } if resource_type == 'asn': request_kwargs['asn'] = int(allocation['value']) elif resource_type == 'router_id': request_kwargs['router_id'] = str(allocation['value']) elif resource_type == 'interface_ip_address': request_kwargs['ip_address'] = str(allocation['value']) request_kwargs['interface'] = endpoint_uuid elif resource_type == 'vlan': request_kwargs['vlan_tag'] = int(allocation['value']) elif resource_type == 'vni': request_kwargs['vni'] = int(allocation['value']) elif resource_type == 'ip': request_kwargs['ip_address'] = str(allocation['value']) elif resource_type == 'loopback': request_kwargs['router_id'] = str(allocation['value']) else: raise Exception(f'Unsupported logical resource type: {resource_type}') return ConfigParameters(**request_kwargs) def _process_logical_resources(self) -> None: if len(self.__logical_resources) == 0: return num_ok, error_list = 0, [] for fabric in self.__logical_resources: fabric_id = str(fabric.get('fabric_id', '')) for resource_type, resource_descriptor in fabric.items(): if resource_type == 'fabric_id': continue allocations = resource_descriptor.get('allocations', {}) for allocation_key, allocation_value in allocations.items(): allocation = dict(allocation_value) allocation['device_uuid'] = allocation_key try: if resource_type == 'interface_ip_address': interface_allocations = allocation.get('interfaces', allocation.get('endpoints', {})) for endpoint_uuid, ip_address in interface_allocations.items(): request = ConfigParameters( device_uuid=str(allocation_key), endpoint_uuid=str(endpoint_uuid), ip_address=str(ip_address), interface=str(endpoint_uuid), name=str(allocation.get('device_name', '')), ) self.__lrs_cli.AddResources(request) num_ok += 1 else: request = self._logical_resource_request(resource_type, allocation) self.__lrs_cli.AddResources(request) num_ok += 1 except Exception as e: # pylint: disable=broad-except error_list.append(f'{fabric_id}/{resource_type}/{allocation_key}: {str(e)}') self.__results.append(('logical_resource', 'add', num_ok, error_list)) @staticmethod def worker(grpc_method, grpc_class, entity) -> Any: return grpc_method(grpc_class(**entity)) Loading src/webui/Dockerfile +2 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,8 @@ COPY --chown=webui:webui src/slice/__init__.py slice/__init__.py COPY --chown=webui:webui src/slice/client/. slice/client/ COPY --chown=webui:webui src/qkd_app/__init__.py qkd_app/__init__.py COPY --chown=webui:webui src/qkd_app/client/. qkd_app/client/ COPY --chown=webui:webui src/logical_resources/__init__.py logical_resources/__init__.py COPY --chown=webui:webui src/logical_resources/client/. logical_resources/client/ COPY --chown=webui:webui src/bgpls_speaker/__init__.py bgpls_speaker/__init__.py COPY --chown=webui:webui src/bgpls_speaker/client/. bgpls_speaker/client/ COPY --chown=webui:webui src/vnt_manager/__init__.py vnt_manager/__init__.py Loading Loading
src/common/tools/descriptor/Loader.py +82 −0 Original line number Diff line number Diff line Loading @@ -40,9 +40,11 @@ from common.proto.context_pb2 import ( Link, LinkId, Service, ServiceId, Slice, SliceId, Topology, TopologyId , OpticalLink ) from common.proto.logical_resources_pb2 import ConfigParameters from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from logical_resources.client.Logicalresourceclient import LogicalResourceClient from service.client.ServiceClient import ServiceClient from slice.client.SliceClient import SliceClient from vnt_manager.client.VNTManagerClient import VNTManagerClient Loading @@ -68,6 +70,7 @@ ENTITY_TO_TEXT = { 'controller': ('Controller', 'Controllers'), 'device' : ('Device', 'Devices' ), 'link' : ('Link', 'Links' ), 'logical_resource': ('Logical Resource', 'Logical Resources'), 'service' : ('Service', 'Services' ), 'slice' : ('Slice', 'Slices' ), 'connection': ('Connection', 'Connections'), Loading Loading @@ -113,6 +116,7 @@ class DescriptorLoader: self, descriptors : Optional[Union[str, Dict]] = None, descriptors_file : Optional[str] = None, num_workers : int = 1, context_client : Optional[ContextClient] = None, device_client : Optional[DeviceClient] = None, logical_resources_client : Optional[LogicalResourceClient] = None, service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None, vntm_client : Optional[VNTManagerClient] = None ) -> None: Loading @@ -136,6 +140,7 @@ class DescriptorLoader: self.__devices = self.__descriptors.get('devices' , []) self.__links = self.__descriptors.get('links' , []) self.__optical_links = self.__descriptors.get('optical_links',[]) self.__logical_resources = self.__descriptors.get('logical_resources', []) self.__services = self.__descriptors.get('services' , []) self.__slices = self.__descriptors.get('slices' , []) self.__ietf_slices = self.__descriptors.get('ietf-network-slice-service:network-slice-services', {}) Loading Loading @@ -194,6 +199,7 @@ class DescriptorLoader: self.__ctx_cli = ContextClient() if context_client is None else context_client self.__dev_cli = DeviceClient() if device_client is None else device_client self.__lrs_cli = LogicalResourceClient() if logical_resources_client is None else logical_resources_client self.__svc_cli = ServiceClient() if service_client is None else service_client self.__slc_cli = SliceClient() if slice_client is None else slice_client self.__vnt_cli = VNTManagerClient() if vntm_client is None else vntm_client Loading Loading @@ -258,6 +264,12 @@ class DescriptorLoader: @property def num_optical_links(self) -> int: return len(self.__optical_links) @property def logical_resources(self) -> List[Dict]: return self.__logical_resources @property def num_logical_resources(self) -> int: return len(self.__logical_resources) @property def services(self) -> Dict[str, List[Dict]]: _services = {} Loading Loading @@ -302,6 +314,8 @@ class DescriptorLoader: self.__services = [format_service_custom_config_rules(service) for service in self.__services] self.__slices = [format_slice_custom_config_rules (slice_ ) for slice_ in self.__slices ] self._process_logical_resources() # Context and Topology require to create the entity first, and add devices, links, services, # slices, etc. in a second stage. self.__contexts_add = get_descriptors_add_contexts(self.__contexts) Loading Loading @@ -403,6 +417,74 @@ class DescriptorLoader: #self.__dev_cli.close() #self.__ctx_cli.close() def _logical_resource_request(self, resource_type: str, allocation: Dict) -> Any: device_uuid = str(allocation.get('device_uuid', '')) endpoint_uuid = str(allocation.get('endpoint_uuid', allocation.get('interface', ''))) device_name = str(allocation.get('device_name', '')) request_kwargs = { 'device_uuid': device_uuid, 'endpoint_uuid': endpoint_uuid, 'name': device_name, } if resource_type == 'asn': request_kwargs['asn'] = int(allocation['value']) elif resource_type == 'router_id': request_kwargs['router_id'] = str(allocation['value']) elif resource_type == 'interface_ip_address': request_kwargs['ip_address'] = str(allocation['value']) request_kwargs['interface'] = endpoint_uuid elif resource_type == 'vlan': request_kwargs['vlan_tag'] = int(allocation['value']) elif resource_type == 'vni': request_kwargs['vni'] = int(allocation['value']) elif resource_type == 'ip': request_kwargs['ip_address'] = str(allocation['value']) elif resource_type == 'loopback': request_kwargs['router_id'] = str(allocation['value']) else: raise Exception(f'Unsupported logical resource type: {resource_type}') return ConfigParameters(**request_kwargs) def _process_logical_resources(self) -> None: if len(self.__logical_resources) == 0: return num_ok, error_list = 0, [] for fabric in self.__logical_resources: fabric_id = str(fabric.get('fabric_id', '')) for resource_type, resource_descriptor in fabric.items(): if resource_type == 'fabric_id': continue allocations = resource_descriptor.get('allocations', {}) for allocation_key, allocation_value in allocations.items(): allocation = dict(allocation_value) allocation['device_uuid'] = allocation_key try: if resource_type == 'interface_ip_address': interface_allocations = allocation.get('interfaces', allocation.get('endpoints', {})) for endpoint_uuid, ip_address in interface_allocations.items(): request = ConfigParameters( device_uuid=str(allocation_key), endpoint_uuid=str(endpoint_uuid), ip_address=str(ip_address), interface=str(endpoint_uuid), name=str(allocation.get('device_name', '')), ) self.__lrs_cli.AddResources(request) num_ok += 1 else: request = self._logical_resource_request(resource_type, allocation) self.__lrs_cli.AddResources(request) num_ok += 1 except Exception as e: # pylint: disable=broad-except error_list.append(f'{fabric_id}/{resource_type}/{allocation_key}: {str(e)}') self.__results.append(('logical_resource', 'add', num_ok, error_list)) @staticmethod def worker(grpc_method, grpc_class, entity) -> Any: return grpc_method(grpc_class(**entity)) Loading
src/webui/Dockerfile +2 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,8 @@ COPY --chown=webui:webui src/slice/__init__.py slice/__init__.py COPY --chown=webui:webui src/slice/client/. slice/client/ COPY --chown=webui:webui src/qkd_app/__init__.py qkd_app/__init__.py COPY --chown=webui:webui src/qkd_app/client/. qkd_app/client/ COPY --chown=webui:webui src/logical_resources/__init__.py logical_resources/__init__.py COPY --chown=webui:webui src/logical_resources/client/. logical_resources/client/ COPY --chown=webui:webui src/bgpls_speaker/__init__.py bgpls_speaker/__init__.py COPY --chown=webui:webui src/bgpls_speaker/client/. bgpls_speaker/client/ COPY --chown=webui:webui src/vnt_manager/__init__.py vnt_manager/__init__.py Loading