Loading src/device/service/DeviceServiceServicerImpl.py +25 −3 Original line number Diff line number Diff line Loading @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Dict import grpc, logging from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty) Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device Loading @@ -27,7 +28,7 @@ from .driver_api.DriverInstanceCache import DriverInstanceCache, get_driver from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI from .Tools import ( check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, get_device_manager_uuid, populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints) Loading Loading @@ -73,9 +74,16 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): errors = [] # Sub-devices and sub-links are exposed by intermediate controllers or represent mgmt links. # They are used to assist in path computation algorithms, and/or to identify dependencies # (which controller is in charge of which sub-device). new_sub_devices : Dict[str, Device] = dict() new_sub_links : Dict[str, Link] = dict() if len(device.device_endpoints) == 0: # created from request, populate endpoints using driver errors.extend(populate_endpoints(device, driver, self.monitoring_loops)) errors.extend(populate_endpoints( device, driver, self.monitoring_loops, new_sub_devices, new_sub_links)) if len(device.device_config.config_rules) == len(connection_config_rules): # created from request, populate config rules using driver Loading @@ -87,12 +95,20 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): for error in errors: LOGGER.error(error) raise OperationFailedException('AddDevice', extra_details=errors) device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED device_id = context_client.SetDevice(device) for sub_device in new_sub_devices.values(): context_client.SetDevice(sub_device) for sub_links in new_sub_links.values(): context_client.SetLink(sub_links) # Update endpoint monitoring resources with UUIDs device_with_uuids = context_client.GetDevice(device_id) populate_endpoint_monitoring_resources(device_with_uuids, self.monitoring_loops) context_client.close() return device_id finally: self.mutex_queues.signal_done(device_uuid) Loading @@ -109,6 +125,12 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') device_manager_uuid = get_device_manager_uuid(device) if device_manager_uuid is not None: device = get_device(context_client, device_manager_uuid, rw_copy=True) if device is None: raise NotFoundException('Device', device_manager_uuid, extra_details='loading in ConfigureDevice') driver : _Driver = get_driver(self.driver_instance_cache, device) if driver is None: msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid)) Loading src/device/service/ErrorMessages.py +3 −2 Original line number Diff line number Diff line Loading @@ -14,9 +14,9 @@ _DEVICE_ID = 'DeviceId({device_uuid:s})' _ENDPOINT_ID = 'EndpointId({endpoint_uuid:s})' _ENDPOINT_DATA = 'EndpointId({endpoint_data:s})' _KPI = 'Kpi({kpi_uuid:s})' _DEVICE_ENDPOINT_ID = _DEVICE_ID + '/' + _ENDPOINT_ID _RESOURCE = 'Resource({resource_data:s})' _RESOURCE_KEY = 'Resource(key={resource_key:s})' _RESOURCE_KEY_VALUE = 'Resource(key={resource_key:s}, value={resource_value:s})' _SUBSCRIPTION = 'Subscription(key={subscr_key:s}, duration={subscr_duration:s}, interval={subscr_interval:s})' Loading @@ -26,7 +26,8 @@ _ERROR = 'Error({error:s})' ERROR_MISSING_DRIVER = _DEVICE_ID + ' has not been added to this Device instance' ERROR_MISSING_KPI = _KPI + ' not found' ERROR_BAD_ENDPOINT = _DEVICE_ID + ': GetConfig retrieved malformed ' + _ENDPOINT_DATA ERROR_BAD_RESOURCE = _DEVICE_ID + ': GetConfig retrieved malformed ' + _RESOURCE ERROR_UNSUP_RESOURCE = _DEVICE_ID + ': GetConfig retrieved unsupported ' + _RESOURCE ERROR_GET = _DEVICE_ID + ': Unable to Get ' + _RESOURCE_KEY + '; ' + _ERROR ERROR_GET_INIT = _DEVICE_ID + ': Unable to Get Initial ' + _RESOURCE_KEY + '; ' + _ERROR Loading src/device/service/Tools.py +123 −21 Original line number Diff line number Diff line Loading @@ -13,19 +13,20 @@ # limitations under the License. import json, logging from typing import Any, Dict, List, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.method_wrappers.ServiceExceptions import InvalidArgumentException from common.proto.context_pb2 import ConfigActionEnum, Device, DeviceConfig from common.proto.context_pb2 import ConfigActionEnum, Device, DeviceConfig, Link from common.proto.device_pb2 import MonitoringSettings from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ( ERROR_BAD_ENDPOINT, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE ERROR_BAD_RESOURCE, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE, ERROR_UNSUP_RESOURCE ) LOGGER = logging.getLogger(__name__) Loading Loading @@ -77,19 +78,51 @@ def check_no_endpoints(device_endpoints) -> None: extra_details='RPC method AddDevice does not accept Endpoints. Endpoints are discovered through '\ 'interrogation of the physical device.') def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : MonitoringLoops) -> List[str]: def get_device_manager_uuid(device : Device) -> Optional[str]: for config_rule in device.device_config.config_rules: if config_rule.WhichOneof('config_rule') != 'custom': continue if config_rule.custom.resource_key != '_manager': continue device_manager_id = json.loads(config_rule.custom.resource_value) return device_manager_id['uuid'] return None def populate_endpoints( device : Device, driver : _Driver, monitoring_loops : MonitoringLoops, new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link] ) -> List[str]: device_uuid = device.device_id.device_uuid.uuid device_name = device.name resources_to_get = [RESOURCE_ENDPOINTS] results_getconfig = driver.GetConfig(resources_to_get) LOGGER.debug('results_getconfig = {:s}'.format(str(results_getconfig))) # first quick pass to identify need of mgmt endpoints and links add_mgmt_port = False for resource_data in results_getconfig: if len(resource_data) != 2: continue resource_key, _ = resource_data if resource_key.startswith('/devices/device'): add_mgmt_port = True break if add_mgmt_port: # add mgmt port to main device device_mgmt_endpoint = device.device_endpoints.add() device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' device_mgmt_endpoint.name = 'mgmt' device_mgmt_endpoint.endpoint_type = 'mgmt' errors : List[str] = list() for endpoint in results_getconfig: if len(endpoint) != 2: errors.append(ERROR_BAD_ENDPOINT.format(device_uuid=device_uuid, endpoint_data=str(endpoint))) for resource_data in results_getconfig: if len(resource_data) != 2: errors.append(ERROR_BAD_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) continue resource_key, resource_value = endpoint resource_key, resource_value = resource_data if isinstance(resource_value, Exception): errors.append(ERROR_GET.format( device_uuid=device_uuid, resource_key=str(resource_key), error=str(resource_value))) Loading @@ -97,20 +130,89 @@ def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : Mon if resource_value is None: continue endpoint_uuid = resource_value.get('uuid') if resource_key.startswith('/devices/device'): # create sub-device _sub_device_uuid = resource_value['uuid'] _sub_device = Device() _sub_device.device_id.device_uuid.uuid = _sub_device_uuid # pylint: disable=no-member _sub_device.name = resource_value['name'] _sub_device.device_type = resource_value['type'] _sub_device.device_operational_status = resource_value['status'] # Sub-devices should not have a driver assigned. Instead, they should have # a config rule specifying their manager. #_sub_device.device_drivers.extend(resource_value['drivers']) # pylint: disable=no-member manager_config_rule = _sub_device.device_config.config_rules.add() manager_config_rule.action = ConfigActionEnum.CONFIGACTION_SET manager_config_rule.custom.resource_key = '_manager' manager = {'uuid': device_uuid, 'name': device_name} manager_config_rule.custom.resource_value = json.dumps(manager, indent=0, sort_keys=True) new_sub_devices[_sub_device_uuid] = _sub_device # add mgmt port to sub-device _sub_device_mgmt_endpoint = _sub_device.device_endpoints.add() # pylint: disable=no-member _sub_device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME _sub_device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME _sub_device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = _sub_device_uuid _sub_device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' _sub_device_mgmt_endpoint.name = 'mgmt' _sub_device_mgmt_endpoint.endpoint_type = 'mgmt' # add mgmt link _mgmt_link_uuid = '{:s}/{:s}=={:s}/{:s}'.format(device_name, 'mgmt', _sub_device.name, 'mgmt') _mgmt_link = Link() _mgmt_link.link_id.link_uuid.uuid = _mgmt_link_uuid # pylint: disable=no-member _mgmt_link.name = _mgmt_link_uuid _mgmt_link.link_endpoint_ids.append(device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member _mgmt_link.link_endpoint_ids.append(_sub_device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member new_sub_links[_mgmt_link_uuid] = _mgmt_link elif resource_key.startswith('/endpoints/endpoint'): endpoint_uuid = resource_value['uuid'] _device_uuid = resource_value.get('device_uuid') endpoint_name = resource_value.get('name') if _device_uuid is None: # add endpoint to current device device_endpoint = device.device_endpoints.add() device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid else: # add endpoint to specified device device_endpoint = new_sub_devices[_device_uuid].device_endpoints.add() device_endpoint.endpoint_id.device_id.device_uuid.uuid = _device_uuid device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid device_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_uuid device_endpoint.endpoint_type = resource_value.get('type') if endpoint_name is not None: device_endpoint.name = endpoint_name device_endpoint.endpoint_type = resource_value.get('type', '-') sample_types : Dict[int, str] = resource_value.get('sample_types', {}) for kpi_sample_type, monitor_resource_key in sample_types.items(): device_endpoint.kpi_sample_types.append(kpi_sample_type) monitoring_loops.add_resource_key(device_uuid, endpoint_uuid, kpi_sample_type, monitor_resource_key) elif resource_key.startswith('/links/link'): # create sub-link _sub_link_uuid = resource_value['uuid'] _sub_link = Link() _sub_link.link_id.link_uuid.uuid = _sub_link_uuid # pylint: disable=no-member _sub_link.name = resource_value['name'] new_sub_links[_sub_link_uuid] = _sub_link for device_uuid,endpoint_uuid in resource_value['name']: _sub_link_endpoint_id = _sub_link.link_endpoint_ids.add() # pylint: disable=no-member _sub_link_endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME _sub_link_endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME _sub_link_endpoint_id.device_id.device_uuid.uuid = device_uuid _sub_link_endpoint_id.endpoint_uuid.uuid = endpoint_uuid else: errors.append(ERROR_UNSUP_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) continue return errors def populate_endpoint_monitoring_resources(device_with_uuids : Device, monitoring_loops : MonitoringLoops) -> None: Loading Loading
src/device/service/DeviceServiceServicerImpl.py +25 −3 Original line number Diff line number Diff line Loading @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import Dict import grpc, logging from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty) Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device Loading @@ -27,7 +28,7 @@ from .driver_api.DriverInstanceCache import DriverInstanceCache, get_driver from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI from .Tools import ( check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, get_device_manager_uuid, populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints) Loading Loading @@ -73,9 +74,16 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): errors = [] # Sub-devices and sub-links are exposed by intermediate controllers or represent mgmt links. # They are used to assist in path computation algorithms, and/or to identify dependencies # (which controller is in charge of which sub-device). new_sub_devices : Dict[str, Device] = dict() new_sub_links : Dict[str, Link] = dict() if len(device.device_endpoints) == 0: # created from request, populate endpoints using driver errors.extend(populate_endpoints(device, driver, self.monitoring_loops)) errors.extend(populate_endpoints( device, driver, self.monitoring_loops, new_sub_devices, new_sub_links)) if len(device.device_config.config_rules) == len(connection_config_rules): # created from request, populate config rules using driver Loading @@ -87,12 +95,20 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): for error in errors: LOGGER.error(error) raise OperationFailedException('AddDevice', extra_details=errors) device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED device_id = context_client.SetDevice(device) for sub_device in new_sub_devices.values(): context_client.SetDevice(sub_device) for sub_links in new_sub_links.values(): context_client.SetLink(sub_links) # Update endpoint monitoring resources with UUIDs device_with_uuids = context_client.GetDevice(device_id) populate_endpoint_monitoring_resources(device_with_uuids, self.monitoring_loops) context_client.close() return device_id finally: self.mutex_queues.signal_done(device_uuid) Loading @@ -109,6 +125,12 @@ class DeviceServiceServicerImpl(DeviceServiceServicer): if device is None: raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') device_manager_uuid = get_device_manager_uuid(device) if device_manager_uuid is not None: device = get_device(context_client, device_manager_uuid, rw_copy=True) if device is None: raise NotFoundException('Device', device_manager_uuid, extra_details='loading in ConfigureDevice') driver : _Driver = get_driver(self.driver_instance_cache, device) if driver is None: msg = ERROR_MISSING_DRIVER.format(device_uuid=str(device_uuid)) Loading
src/device/service/ErrorMessages.py +3 −2 Original line number Diff line number Diff line Loading @@ -14,9 +14,9 @@ _DEVICE_ID = 'DeviceId({device_uuid:s})' _ENDPOINT_ID = 'EndpointId({endpoint_uuid:s})' _ENDPOINT_DATA = 'EndpointId({endpoint_data:s})' _KPI = 'Kpi({kpi_uuid:s})' _DEVICE_ENDPOINT_ID = _DEVICE_ID + '/' + _ENDPOINT_ID _RESOURCE = 'Resource({resource_data:s})' _RESOURCE_KEY = 'Resource(key={resource_key:s})' _RESOURCE_KEY_VALUE = 'Resource(key={resource_key:s}, value={resource_value:s})' _SUBSCRIPTION = 'Subscription(key={subscr_key:s}, duration={subscr_duration:s}, interval={subscr_interval:s})' Loading @@ -26,7 +26,8 @@ _ERROR = 'Error({error:s})' ERROR_MISSING_DRIVER = _DEVICE_ID + ' has not been added to this Device instance' ERROR_MISSING_KPI = _KPI + ' not found' ERROR_BAD_ENDPOINT = _DEVICE_ID + ': GetConfig retrieved malformed ' + _ENDPOINT_DATA ERROR_BAD_RESOURCE = _DEVICE_ID + ': GetConfig retrieved malformed ' + _RESOURCE ERROR_UNSUP_RESOURCE = _DEVICE_ID + ': GetConfig retrieved unsupported ' + _RESOURCE ERROR_GET = _DEVICE_ID + ': Unable to Get ' + _RESOURCE_KEY + '; ' + _ERROR ERROR_GET_INIT = _DEVICE_ID + ': Unable to Get Initial ' + _RESOURCE_KEY + '; ' + _ERROR Loading
src/device/service/Tools.py +123 −21 Original line number Diff line number Diff line Loading @@ -13,19 +13,20 @@ # limitations under the License. import json, logging from typing import Any, Dict, List, Tuple, Union from typing import Any, Dict, List, Optional, Tuple, Union from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.method_wrappers.ServiceExceptions import InvalidArgumentException from common.proto.context_pb2 import ConfigActionEnum, Device, DeviceConfig from common.proto.context_pb2 import ConfigActionEnum, Device, DeviceConfig, Link from common.proto.device_pb2 import MonitoringSettings from common.proto.kpi_sample_types_pb2 import KpiSampleType from common.tools.grpc.ConfigRules import update_config_rule_custom from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from .driver_api._Driver import _Driver, RESOURCE_ENDPOINTS from .monitoring.MonitoringLoops import MonitoringLoops from .ErrorMessages import ( ERROR_BAD_ENDPOINT, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE ERROR_BAD_RESOURCE, ERROR_DELETE, ERROR_GET, ERROR_GET_INIT, ERROR_MISSING_KPI, ERROR_SAMPLETYPE, ERROR_SET, ERROR_SUBSCRIBE, ERROR_UNSUBSCRIBE, ERROR_UNSUP_RESOURCE ) LOGGER = logging.getLogger(__name__) Loading Loading @@ -77,19 +78,51 @@ def check_no_endpoints(device_endpoints) -> None: extra_details='RPC method AddDevice does not accept Endpoints. Endpoints are discovered through '\ 'interrogation of the physical device.') def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : MonitoringLoops) -> List[str]: def get_device_manager_uuid(device : Device) -> Optional[str]: for config_rule in device.device_config.config_rules: if config_rule.WhichOneof('config_rule') != 'custom': continue if config_rule.custom.resource_key != '_manager': continue device_manager_id = json.loads(config_rule.custom.resource_value) return device_manager_id['uuid'] return None def populate_endpoints( device : Device, driver : _Driver, monitoring_loops : MonitoringLoops, new_sub_devices : Dict[str, Device], new_sub_links : Dict[str, Link] ) -> List[str]: device_uuid = device.device_id.device_uuid.uuid device_name = device.name resources_to_get = [RESOURCE_ENDPOINTS] results_getconfig = driver.GetConfig(resources_to_get) LOGGER.debug('results_getconfig = {:s}'.format(str(results_getconfig))) # first quick pass to identify need of mgmt endpoints and links add_mgmt_port = False for resource_data in results_getconfig: if len(resource_data) != 2: continue resource_key, _ = resource_data if resource_key.startswith('/devices/device'): add_mgmt_port = True break if add_mgmt_port: # add mgmt port to main device device_mgmt_endpoint = device.device_endpoints.add() device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' device_mgmt_endpoint.name = 'mgmt' device_mgmt_endpoint.endpoint_type = 'mgmt' errors : List[str] = list() for endpoint in results_getconfig: if len(endpoint) != 2: errors.append(ERROR_BAD_ENDPOINT.format(device_uuid=device_uuid, endpoint_data=str(endpoint))) for resource_data in results_getconfig: if len(resource_data) != 2: errors.append(ERROR_BAD_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) continue resource_key, resource_value = endpoint resource_key, resource_value = resource_data if isinstance(resource_value, Exception): errors.append(ERROR_GET.format( device_uuid=device_uuid, resource_key=str(resource_key), error=str(resource_value))) Loading @@ -97,20 +130,89 @@ def populate_endpoints(device : Device, driver : _Driver, monitoring_loops : Mon if resource_value is None: continue endpoint_uuid = resource_value.get('uuid') if resource_key.startswith('/devices/device'): # create sub-device _sub_device_uuid = resource_value['uuid'] _sub_device = Device() _sub_device.device_id.device_uuid.uuid = _sub_device_uuid # pylint: disable=no-member _sub_device.name = resource_value['name'] _sub_device.device_type = resource_value['type'] _sub_device.device_operational_status = resource_value['status'] # Sub-devices should not have a driver assigned. Instead, they should have # a config rule specifying their manager. #_sub_device.device_drivers.extend(resource_value['drivers']) # pylint: disable=no-member manager_config_rule = _sub_device.device_config.config_rules.add() manager_config_rule.action = ConfigActionEnum.CONFIGACTION_SET manager_config_rule.custom.resource_key = '_manager' manager = {'uuid': device_uuid, 'name': device_name} manager_config_rule.custom.resource_value = json.dumps(manager, indent=0, sort_keys=True) new_sub_devices[_sub_device_uuid] = _sub_device # add mgmt port to sub-device _sub_device_mgmt_endpoint = _sub_device.device_endpoints.add() # pylint: disable=no-member _sub_device_mgmt_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME _sub_device_mgmt_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME _sub_device_mgmt_endpoint.endpoint_id.device_id.device_uuid.uuid = _sub_device_uuid _sub_device_mgmt_endpoint.endpoint_id.endpoint_uuid.uuid = 'mgmt' _sub_device_mgmt_endpoint.name = 'mgmt' _sub_device_mgmt_endpoint.endpoint_type = 'mgmt' # add mgmt link _mgmt_link_uuid = '{:s}/{:s}=={:s}/{:s}'.format(device_name, 'mgmt', _sub_device.name, 'mgmt') _mgmt_link = Link() _mgmt_link.link_id.link_uuid.uuid = _mgmt_link_uuid # pylint: disable=no-member _mgmt_link.name = _mgmt_link_uuid _mgmt_link.link_endpoint_ids.append(device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member _mgmt_link.link_endpoint_ids.append(_sub_device_mgmt_endpoint.endpoint_id) # pylint: disable=no-member new_sub_links[_mgmt_link_uuid] = _mgmt_link elif resource_key.startswith('/endpoints/endpoint'): endpoint_uuid = resource_value['uuid'] _device_uuid = resource_value.get('device_uuid') endpoint_name = resource_value.get('name') if _device_uuid is None: # add endpoint to current device device_endpoint = device.device_endpoints.add() device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid else: # add endpoint to specified device device_endpoint = new_sub_devices[_device_uuid].device_endpoints.add() device_endpoint.endpoint_id.device_id.device_uuid.uuid = _device_uuid device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME device_endpoint.endpoint_id.device_id.device_uuid.uuid = device_uuid device_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_uuid device_endpoint.endpoint_type = resource_value.get('type') if endpoint_name is not None: device_endpoint.name = endpoint_name device_endpoint.endpoint_type = resource_value.get('type', '-') sample_types : Dict[int, str] = resource_value.get('sample_types', {}) for kpi_sample_type, monitor_resource_key in sample_types.items(): device_endpoint.kpi_sample_types.append(kpi_sample_type) monitoring_loops.add_resource_key(device_uuid, endpoint_uuid, kpi_sample_type, monitor_resource_key) elif resource_key.startswith('/links/link'): # create sub-link _sub_link_uuid = resource_value['uuid'] _sub_link = Link() _sub_link.link_id.link_uuid.uuid = _sub_link_uuid # pylint: disable=no-member _sub_link.name = resource_value['name'] new_sub_links[_sub_link_uuid] = _sub_link for device_uuid,endpoint_uuid in resource_value['name']: _sub_link_endpoint_id = _sub_link.link_endpoint_ids.add() # pylint: disable=no-member _sub_link_endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME _sub_link_endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME _sub_link_endpoint_id.device_id.device_uuid.uuid = device_uuid _sub_link_endpoint_id.endpoint_uuid.uuid = endpoint_uuid else: errors.append(ERROR_UNSUP_RESOURCE.format(device_uuid=device_uuid, resource_data=str(resource_data))) continue return errors def populate_endpoint_monitoring_resources(device_with_uuids : Device, monitoring_loops : MonitoringLoops) -> None: Loading