Commit 5bfe1990 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

HW inventroy NBI

1) Yang handler file
2) Hardware inventory file
3) Minor changes
parent 6617dd10
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ from common.Constants import ServiceNameEnum
from common.Settings import (
    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
    wait_for_environment_variables)
from src.nbi.service.rest_server.nbi_plugins.ietf_hardware import register_ietf_hardware

from .NbiService import NbiService
from .rest_server.RestServer import RestServer
from .rest_server.nbi_plugins.etsi_bwm import register_etsi_bwm_api
@@ -27,6 +27,7 @@ from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn
from .rest_server.nbi_plugins.ietf_network import register_ietf_network
from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss
from .rest_server.nbi_plugins.tfs_api import register_tfs_api
from .rest_server.nbi_plugins.ietf_hardware import register_ietf_hardware

terminate = threading.Event()
LOGGER = None
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ class Hardware(Resource):
            if device is None:
                raise Exception('Device({:s}) not found in database'.format(str(device_uuid)))

            yang_handler = YangHandler('ietf-hardware')
            yang_handler = YangHandler()
            hardware_reply = yang_handler.compose(device)
            yang_handler.destroy()

+46 −10
Original line number Diff line number Diff line
@@ -2,17 +2,27 @@ import libyang, os
from common.proto.context_pb2 import Device
from typing import Dict, Optional

import logging
import re
import datetime

LOGGER = logging.getLogger(__name__)
YANG_DIR = os.path.join(os.path.dirname(__file__), 'yang')
MODULE_NAME = 'ietf-hardware'
YANG_MODULES = [
    'iana-hardware',
    'ietf-hardware'
]

class YangHandler:
    def __init__(self) -> None:
        self._yang_context = libyang.Context(YANG_DIR)
        self._yang_module  = self._yang_context.load_module(MODULE_NAME)
        self._yang_module.feature_enable_all()
        for yang_module_name in YANG_MODULES:
            LOGGER.info('Loading module: {:s}'.format(str(yang_module_name)))
            self._yang_context.load_module(yang_module_name).feature_enable_all()

    def parse_to_dict(self, message : Dict) -> Dict:
        dnode : Optional[libyang.DNode] = self._yang_module.parse_data_dict(
        yang_module = self._yang_context.get_module('ietf-hardware')
        dnode : Optional[libyang.DNode] = yang_module.parse_data_dict(
            message, validate_present=True, validate=True, strict=True
        )
        if dnode is None: raise Exception('Unable to parse Message({:s})'.format(str(message)))
@@ -20,11 +30,31 @@ class YangHandler:
        dnode.free()
        return message

    
    @staticmethod
    def convert_to_iso_date(date_str: str) -> Optional[str]:
        date_str = date_str.strip('"')
        # Define the regex pattern for ISO 8601 date format
        pattern = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[\+\-]\d{2}:\d{2})"
        # Check if the input date string matches the pattern
        if re.match(pattern, date_str):
            return date_str  # Already in ISO format
        else:
            try:
                # Parse the input date string as a datetime object
                datetime_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d")
                # Convert to ISO format
                iso_date = datetime_obj.isoformat() + "Z"
                return iso_date
            except ValueError:
                return None  # Invalid date format


    def compose(self, device : Device) -> Dict:
        # compose device iterating through the components
 
        hardware = self._yang_context.create_data_path('/ietf-hardware:hardware')
        physical_index = 0
        physical_index = 1
        
        for component in device.components:
            attributes = component.attributes
@@ -39,29 +69,35 @@ class YangHandler:

            if component_type == "FRU" :
                component_type = "slack"
                component_new.create_path('isfru', True)
                component_new.create_path('is-fru', True)
            else :
                component_new.create_path('isfru', False)
                component_new.create_path('is-fru', False)
                
            component_type = component_type.replace("_", "-").lower()
            component_type = 'iana-hardware:' + component_type

            component_new.create_path('class', component_type)

            #Añadir resto de atributos en IETF

            physical_index += physical_index
            physical_index += 1
            component_new.create_path('physical-index', physical_index)

            component_new.create_path('description', attributes["description"])

            component_new.create_path('parent', component.parent)

            if attributes["mfg-date"] != "":
                mfg_date = self.convert_to_iso_date(attributes["mfg-date"])
                LOGGER.info('component[name="{:s}"]'.format(attributes["mfg-date"]))
                component_new.create_path('mfg-date', mfg_date)

            component_new.create_path('hardware-rev', attributes["hardware-rev"])
            component_new.create_path('software-rev', attributes["software-rev"])
            component_new.create_path('firmware-rev', attributes["firmware-version"])
            component_new.create_path('serial-num', attributes["serial-num"])
            component_new.create_path('mfg-name', attributes["mfg-name"])
            component_new.create_path('mfg-date', attributes["mfg-date"])
            if attributes["id"]:
                component_new.create_path('parent-rel-pos', attributes["id"])
            
            component_new.create_path('uri', component.name)
+1 −1
Original line number Diff line number Diff line
from nbi.service.rest_server.nbi_plugins.ietf_hardware.Hardware import Hardware
from nbi.service.rest_server.RestServer import RestServer

URL_PREFIX = "/restconf/data/device=<device_uuid>/ietf-hardware:hardware"
URL_PREFIX = "/restconf/data/device=<path:device_uuid>/ietf-hardware:hardware"

def register_ietf_hardware(rest_server: RestServer):
    rest_server.add_resource(Hardware, URL_PREFIX)
 No newline at end of file
+3 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ from nbi.service.rest_server.RestServer import RestServer
from .Resources import (
    Connection, ConnectionIds, Connections,
    Context, ContextIds, Contexts,
    Device, DeviceIds, Deviceshw,
    Device, DeviceIds, Devices, Deviceshw,
    DummyContexts,
    Link, LinkIds, Links,
    PolicyRule, PolicyRuleIds, PolicyRules,
@@ -46,11 +46,11 @@ RESOURCES = [
    ('api.slice_ids',      SliceIds,      '/context/<path:context_uuid>/slice_ids'),
    ('api.slices',         Slices,        '/context/<path:context_uuid>/slices'),
    ('api.slice',          Slice,         '/context/<path:context_uuid>/slice/<path:slice_uuid>'),
'''

    ('api.device_ids',     DeviceIds,     '/device_ids'),
    ('api.devices',        Devices,       '/devices'),
    ('api.device',         Device,        '/device/<path:device_uuid>'),
    '''
    
    ('api.deviceshw',        Deviceshw,       '/device/<path:device_uuid>/hardware'),
    
    ('api.link_ids',       LinkIds,       '/link_ids'),