From ed44430154c50310a8221942cc39b28a9574a56a Mon Sep 17 00:00:00 2001
From: armingol <pablo.armingolrobles@telefonica.com>
Date: Mon, 30 Sep 2024 15:42:24 +0200
Subject: [PATCH] code cleanup

---
 .../nbi_plugins/ietf_hardware/YangHandler.py  |  22 +-
 .../nbi_plugins/ietf_hardware/__init__.py     |   1 +
 ...network-hardware-inventory@2023-03-09.yang | 604 ++++++++++++++++++
 3 files changed, 621 insertions(+), 6 deletions(-)
 create mode 100644 src/nbi/service/rest_server/nbi_plugins/ietf_hardware/yang/ietf-network-hardware-inventory@2023-03-09.yang

diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/YangHandler.py b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/YangHandler.py
index 0b857ab83..724dcc37f 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/YangHandler.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/YangHandler.py
@@ -12,19 +12,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import libyang, os
 from common.proto.context_pb2 import Device
 from typing import Dict, Optional
+import datetime
 import json
 import logging
+import libyang
+import os
 import re
-import datetime
 
 LOGGER = logging.getLogger(__name__)
 YANG_DIR = os.path.join(os.path.dirname(__file__), 'yang')
 YANG_MODULES = [
     'iana-hardware',
-    'ietf-hardware'
+    'ietf-hardware',
+    'ietf-network-hardware-inventory'
 ]
 
 class YangHandler:
@@ -35,7 +37,7 @@ class YangHandler:
             self._yang_context.load_module(yang_module_name).feature_enable_all()
 
     def parse_to_dict(self, message : Dict) -> Dict:
-        yang_module = self._yang_context.get_module('ietf-hardware')
+        yang_module = self._yang_context.get_module('ietf-network-hardware-inventory')
         dnode : Optional[libyang.DNode] = yang_module.parse_data_dict(
             message, validate_present=True, validate=True, strict=True
         )
@@ -77,6 +79,7 @@ class YangHandler:
                 component_type = "module"
             if component_type == "FRU" :
                 component_type = "slack"
+
             component_type = component_type.replace("_", "-").lower()
             component_type = 'iana-hardware:' + component_type
             component_new.create_path('class', component_type)
@@ -91,7 +94,6 @@ class YangHandler:
                       break
             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"])
@@ -107,7 +109,15 @@ class YangHandler:
                     component_new.create_path('is-fru', False)
 
             if attributes["id"]:
-                component_new.create_path('parent-rel-pos', attributes["id"])
+                try:
+                    if  "CHASSIS" in component.type :  
+                        component_new.create_path('parent-rel-pos', 0)
+                    else:                        
+                        parent_rel_pos = int(attributes["id"].replace("\"", ""))
+                        component_new.create_path('parent-rel-pos', parent_rel_pos)
+                except ValueError:
+                    LOGGER.info('ERROR:{:s} '.format(component.name ))
+                    continue
             
             component_new.create_path('uri', component.name)
             component_new.create_path('uuid', component.component_uuid.uuid)
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/__init__.py b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/__init__.py
index 7a9eec506..ba774650e 100644
--- a/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/__init__.py
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/__init__.py
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 from nbi.service.rest_server.nbi_plugins.ietf_hardware.Hardware import Hardware
+from nbi.service.rest_server.nbi_plugins.ietf_hardware.HardwareMultipleDevices import HardwareMultipleDevices
 from nbi.service.rest_server.RestServer import RestServer
 
 URL_PREFIX_DEVICE   = "/restconf/data/device=<path:device_uuid>/ietf-network-hardware-inventory:network-hardware-inventory"
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/yang/ietf-network-hardware-inventory@2023-03-09.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/yang/ietf-network-hardware-inventory@2023-03-09.yang
new file mode 100644
index 000000000..e074e3005
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_hardware/yang/ietf-network-hardware-inventory@2023-03-09.yang
@@ -0,0 +1,604 @@
+module ietf-network-hardware-inventory {
+  yang-version 1.1;
+  namespace
+    "urn:ietf:params:xml:ns:yang:ietf-network-hardware-inventory";
+  prefix nhi;
+
+  import ietf-yang-types {
+    prefix yang;
+    reference
+      "RFC6991: Common YANG Data Types.";
+  }
+
+  import iana-hardware {
+    prefix ianahw;
+    reference
+      "https://www.iana.org/assignments/yang-parameters";
+  }
+
+  import ietf-inet-types {
+    prefix inet;
+    reference
+      "RFC6991: Common YANG Data Types.";
+  }
+
+  organization
+    "IETF CCAMP Working Group";
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/ccamp/>
+     WG List:  <mailto:ccamp@ietf.org>
+
+     Editor:   Chaode Yu
+               <yuchaode@huawei.com>
+
+     Editor:   Italo Busi
+               <italo.busi@huawei.com>
+
+     Editor:   Aihua Guo
+               <aihuaguo.ietf@gmail.com>
+
+     Editor:   Sergio Belotti
+               <sergio.belotti@nokia.com>
+
+     Editor:   Jean-Francois Bouquier
+               <jeff.bouquier@vodafone.com>
+
+     Editor:   Fabio Peruzzini
+               <fabio.peruzzini@telecomitalia.it>";
+
+  description
+    "This module defines a model for retrieving network hardware
+    inventory.
+
+    The model fully conforms to the Network Management
+    Datastore Architecture (NMDA).
+    Copyright (c) 2022 IETF Trust and the persons
+    identified as authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Revised BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (https://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC XXXX; see
+    the RFC itself for full legal notices.
+
+    The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
+    NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
+    'MAY', and 'OPTIONAL' in this document are to be interpreted as
+    described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
+    they appear in all capitals, as shown here.";
+
+  // RFC Ed.: replace XXXX with actual RFC number and remove this
+  // note.
+  // RFC Ed.: update the date below with the date of RFC publication
+  // and remove this note.
+
+  revision 2023-03-09 {
+    description
+      "Initial version";
+    reference
+      "RFC XXXX: A YANG Data Model for Network Hardware Inventory.";
+      //RFC Editor: replace XXXX with actual RFC number, update date
+      //information and remove this note
+  }
+
+  container network-hardware-inventory {
+    config false;
+    description
+      "The top-level container for the network inventory
+      information.";
+    uses equipment-rooms-grouping;
+    uses network-elements-grouping;
+  }
+
+  grouping common-entity-attributes {
+    description
+      "A set of attributes which are common to all the entities
+      (e.g., component, equipment room) defined in this module.";
+    leaf uuid {
+      type yang:uuid;
+      description
+        "Uniquely identifies an entity (e.g., component).";
+    }
+    leaf name {
+      type string;
+      description
+        "A name for an entity (e.g., component), as specified by
+        a network manager, that provides a non-volatile 'handle'
+        for the entity and that can be modified anytime during the
+        entity lifetime.
+
+        If no configured value exists, the server MAY set the value
+        of this node to a locally unique value in the operational
+        state.";
+    }
+    leaf description {
+      type string;
+      description "a textual description of inventory object";
+    }
+    leaf alias {
+      type string;
+      description
+      "a alias name of inventory objects. This alias name can be
+      specified by network manager.";
+    }
+  }
+
+  grouping network-elements-grouping {
+    description
+      "The attributes of the network elements.";
+    container network-elements {
+      description
+        "The container for the list of network elements.";
+      list network-element {
+        key uuid;
+        description
+          "The list of network elements within the network.";
+        uses common-entity-attributes;
+        container ne-location {
+          description
+            "The location information of this network element.";
+          leaf-list equipment-room-name {
+            type leafref {
+              path "/nhi:network-hardware-inventory/" +
+                   "nhi:equipment-rooms/nhi:equipment-room/nhi:name";
+            }
+            description
+              "Names of equipment rooms where the NE is located.
+              Please note that a NE could be located in several
+              equipment rooms.";
+          }
+        }
+        uses ne-specific-info-grouping;
+        uses components-grouping;
+      }
+    }
+  }
+
+  grouping ne-specific-info-grouping {
+    description
+      "Attributes applicable to network elements.";
+    leaf hardware-rev {
+      type string;
+      description
+        "The vendor-specific hardware revision string for the NE.";
+    }
+    leaf software-rev {
+      type string;
+      description
+        "The vendor-specific software revision string for the NE.";
+    }
+    leaf mfg-name {
+      type string;
+      description "The name of the manufacturer of this NE";
+    }
+    leaf mfg-date {
+      type yang:date-and-time;
+      description "The date of manufacturing of the NE.";
+    }
+    leaf part-number {
+      type string;
+      description
+        "The vendor-specific model name identifier string associated
+         with this NE.  The preferred value is the customer-visible
+         part number, which may be printed on the NE itself.";
+    }
+    leaf serial-number {
+      type string;
+      description
+        "The vendor-specific serial number string for the NE";
+    }
+    leaf product-name {
+      type string;
+      description
+        "indicates the vendor-spefic device type infomation.";
+    }
+  }
+
+  grouping equipment-rooms-grouping {
+    description
+      "The attributes of the equipment rooms.";
+    container equipment-rooms {
+      description
+        "The container for the list of equipment rooms.";
+      list equipment-room {
+        key uuid;
+        description
+          "The list of equipment rooms within the network.";
+        uses common-entity-attributes;
+        leaf location {
+          type string;
+          description
+            "compared with the location information of the other
+            inventory objects, a GIS address is preferred for
+            equipment room";
+        }
+        container racks {
+          description
+            "Top level container for the list of racks.";
+          list rack {
+            key uuid;
+            description
+              "The list of racks within an equipment room.";
+            uses common-entity-attributes;
+            uses rack-specific-info-grouping;
+            list contained-chassis {
+              key "ne-ref component-ref";
+              description
+                "The list of chassis within a rack.";
+              leaf ne-ref {
+                type leafref {
+                  path "/nhi:network-hardware-inventory"
+                  + "/nhi:network-elements/nhi:network-element"
+                  + "/nhi:uuid";
+                }
+                description
+                  "The reference to the network element containing
+                  the chassis component.";
+              }
+              leaf component-ref {
+                type leafref {
+                  path "/nhi:network-hardware-inventory"
+                  + "/nhi:network-elements/nhi:network-element"
+                  + "[nhi:uuid=current()/../ne-ref]/nhi:components"
+                  + "/nhi:component/nhi:uuid";
+                }
+                description
+                  "The reference to the chassis component within
+                  the network element and contained by the rack.";
+              }
+              leaf relative-position {
+                type uint8;
+                description "A relative position of chassis within
+                the rack";
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  grouping rack-specific-info-grouping {
+    description
+      "Attributes applicable to racks only.";
+    container rack-location {
+      description
+        "The location information of the rack, which comprises the
+        name of the equipment room, row number, and column number.";
+      leaf equipment-room-name {
+        type leafref {
+          path "/nhi:network-hardware-inventory/nhi:equipment-rooms"
+          + "/nhi:equipment-room/nhi:name";
+        }
+        description
+        "Name of equipment room where this rack is located.";
+      }
+      leaf row-number {
+        type uint32;
+        description
+          "Identifies the row within the equipment room where
+          the rack is located.";
+      }
+      leaf column-number {
+        type uint32;
+        description
+          "Identifies the physical location of the rack within
+          the column.";
+      }
+    }
+    leaf height {
+      type uint16;
+      units millimeter;
+      description
+        "Rack height.";
+    }
+    leaf width {
+      type uint16;
+      units millimeter;
+      description
+        "Rack width.";
+    }
+    leaf depth {
+      type uint16;
+      units millimeter;
+      description
+        "Rack depth.";
+    }
+    leaf max-voltage {
+      type uint16;
+      units volt;
+      description
+        "The maximum voltage could be supported by the rack.";
+    }
+  }
+
+  grouping components-grouping {
+    description
+      "The attributes of the hardware components.";
+    container components {
+      description
+        "The container for the list of components.";
+      list component {
+        key uuid;
+        description
+          "The list of components within a network element.";
+        uses common-entity-attributes;
+        leaf location {
+          type string;
+          description
+            "A relative location information of this component.
+            In optical transport network, the location string is
+            using the following pattern:
+              '/ne=<nw-ne-name>[/r=<r_index>][/sh=<sh_index>
+              [/s_sh=<s_sh_index> ...]][[/sl=<sl_index>
+              [/s_sl=<s_sl_index> ...]][/p=<p_index> …]]'
+            ";
+        }
+        leaf class {
+          type identityref {
+            base ianahw:hardware-class;
+          }
+          description
+            "An indication of the general hardware type of the
+             component.";
+          reference
+            "RFC 8348: A YANG Data Model for Hardware Management.";
+        }
+        leaf-list contained-child {
+          type leafref {
+            path "../nhi:uuid";
+          }
+          description
+            "The list of the identifiers of the child components
+            physically contained within this component.";
+        }
+        leaf parent-rel-pos {
+          type int32 {
+            range "0 .. 2147483647";
+          }
+          description
+            "The relative position with respect to the parent
+            component among all the sibling components.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+                       entPhysicalParentRelPos";
+        }
+
+        container parent-component-references {
+          description
+              "The top level container for the list of the
+              identifiers of the parents of this component in a
+              hierarchy.";
+          list component-reference {
+            key index;
+            description
+              "The list of the identifiers of the parents of this
+              component in a hierarchy.
+
+              The index parameter defines the hierarchy: the topmost
+              parent has an index of 0.";
+            leaf index {
+              type uint8;
+              description
+                "The index of the parent with respect to the
+                hierarchy.";
+            }
+            leaf class {
+              type leafref {
+                path "../../../nhi:class";
+              }
+              description
+                "Class of the hierarchial parent component.";
+            }
+            leaf uuid {
+              type leafref {
+                path "../../../nhi:uuid";
+              }
+              description
+                "The identifier of the parent's component in the
+                hierarchy.";
+            }
+          }
+        }
+
+        leaf hardware-rev {
+          type string;
+          description
+            "The vendor-specific hardware revision string for the
+             component.  The preferred value is the hardware revision
+             identifier actually printed on the component itself (if
+             present).";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+                       entPhysicalHardwareRev";
+        }
+        leaf firmware-rev {
+          type string;
+          description
+            "The vendor-specific firmware revision string for the
+             component.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+                       entPhysicalFirmwareRev";
+        }
+        leaf software-rev {
+          type string;
+          description
+            "The vendor-specific software revision string for the
+             component.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+                       entPhysicalSoftwareRev";
+        }
+        leaf serial-num {
+          type string;
+          description
+            "The vendor-specific serial number string for the
+             component.  The preferred value is the serial number
+             string actually printed on the component itself (if
+             present).";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+            entPhysicalSerialNum";
+        }
+        leaf mfg-name {
+          type string;
+          description
+            "The name of the manufacturer of this physical component.
+             The preferred value is the manufacturer name string
+             actually printed on the component itself (if present).
+
+             Note that comparisons between instances of the
+             'model-name', 'firmware-rev', 'software-rev', and
+             'serial-num' nodes are only meaningful amongst
+             components with the same value of 'mfg-name'.
+
+             If the manufacturer name string associated with the
+             physical component is unknown to the server, then this
+             node is not instantiated.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgName";
+        }
+        leaf part-number {
+          type string;
+          description
+            "The vendor-specific model name identifier string
+             associated with this physical component.  The preferred
+             value is the customer-visible part number, which may be
+             printed on the component itself.
+
+             If the model name string associated with the physical
+             component is unknown to the server, then this node is
+             not instantiated.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) -
+            entPhysicalModelName";
+        }
+        leaf asset-id {
+          type string;
+          description
+            "This node is a user-assigned asset tracking identifier
+             for the component.
+
+             A server implementation MAY map this leaf to the
+             entPhysicalAssetID MIB object.  Such an implementation
+             needs to use some mechanism to handle the differences in
+             size and characters allowed between this leaf and
+             entPhysicalAssetID.  The definition of such a mechanism
+             is outside the scope of this document.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) - entPhysicalAssetID";
+        }
+        leaf is-fru {
+          type boolean;
+          description
+            "This node indicates whether or not this component is
+             considered a 'field-replaceable unit' by the vendor.  If
+             this node contains the value 'true', then this component
+             identifies a field-replaceable unit.  For all components
+             that are permanently contained within a
+             field-replaceable unit, the value 'false' should be
+             returned for this node.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) - entPhysicalIsFRU";
+        }
+        leaf mfg-date {
+          type yang:date-and-time;
+          description
+            "The date of manufacturing of the managed component.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) - entPhysicalMfgDate";
+        }
+        leaf-list uri {
+          type inet:uri;
+          description
+            "This node contains identification information about the
+             component.";
+          reference
+            "RFC 6933: Entity MIB (Version 4) - entPhysicalUris";
+        }
+        uses component-specific-info-grouping;
+      }
+    }
+  }
+
+  grouping component-specific-info-grouping {
+    description
+      "In case if there are some missing attributes of component not
+      defined by RFC8348. These attributes could be
+      component-specific.
+      Here we provide a extension structure for all the components
+      we recognized. We will enrich these component specifc
+      containers in the future.";
+    choice component-class {
+      description
+        "This extension differs between different component
+        classes.";
+      case chassis {
+        when "./class = 'ianahw:chassis'";
+        container chassis-specific-info {
+          description
+            "This container contains some attributes belong to
+            chassis only.";
+          uses chassis-specific-info-grouping;
+        }
+      }
+      case container {
+        when "./class = 'ianahw:container'";
+        container slot-specific-info {
+          description
+            "This container contains some attributes belong to
+            slot or sub-slot only.";
+          uses slot-specific-info-grouping;
+        }
+      }
+      case module {
+        when "./nhi:class = 'ianahw:module'";
+        container board-specific-info {
+          description
+            "This container contains some attributes belong to
+            board only.";
+          uses board-specific-info-grouping;
+        }
+      }
+      case port {
+        when "./nhi:class = 'ianahw:port'";
+        container port-specific-info {
+          description
+            "This container contains some attributes belong to
+            port only.";
+          uses port-specific-info-grouping;
+        }
+      }
+    //TO BE ADDED: transceiver
+    }
+  }
+
+  grouping chassis-specific-info-grouping {
+  //To be enriched in the future.
+    description
+      "Specific attributes applicable to chassis only.";
+  }
+
+  grouping slot-specific-info-grouping {
+  //To be enriched in the future.
+    description
+      "Specific attributes applicable to slots only.";
+  }
+
+  grouping board-specific-info-grouping {
+  //To be enriched in the future.
+    description
+      "Specific attributes applicable to boards only.";
+  }
+
+  grouping port-specific-info-grouping {
+  //To be enriched in the future.
+    description
+      "Specific attributes applicable to ports only.";
+  }
+}
-- 
GitLab