From 4aad821d8306dfe7767ac54b060a72f15a8f15ee Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 29 Dec 2020 19:08:43 -0800 Subject: [PATCH] [sysName]: Implement sysName OID (#185) [sysName]: Add sysName OID implementation in snmpagent. sysName OID is currently supported by snmpd. Override this implementation to make sure the latest hostname is taken from config db. Add a new MIB class to support retrieving sysName from config_db Add unit-test to test sysName OID. --- src/sonic_ax_impl/main.py | 1 + src/sonic_ax_impl/mibs/ietf/rfc1213.py | 29 ++++++++++++++ tests/mock_tables/config_db.json | 4 ++ tests/mock_tables/global_db/config_db.json | 4 ++ tests/namespace/test_sysname.py | 44 ++++++++++++++++++++++ tests/test_sysname.py | 38 +++++++++++++++++++ 6 files changed, 120 insertions(+) create mode 100644 tests/namespace/test_sysname.py create mode 100644 tests/test_sysname.py diff --git a/src/sonic_ax_impl/main.py b/src/sonic_ax_impl/main.py index 763b4b0c77ad..672a70171945 100644 --- a/src/sonic_ax_impl/main.py +++ b/src/sonic_ax_impl/main.py @@ -24,6 +24,7 @@ class SonicMIB( rfc1213.InterfacesMIB, rfc1213.IpMib, + rfc1213.SysNameMIB, rfc2737.PhysicalTableMIB, rfc3433.PhysicalSensorTableMIB, rfc2863.InterfaceMIBObjects, diff --git a/src/sonic_ax_impl/mibs/ietf/rfc1213.py b/src/sonic_ax_impl/mibs/ietf/rfc1213.py index b2d522194e26..7fded5e7b584 100644 --- a/src/sonic_ax_impl/mibs/ietf/rfc1213.py +++ b/src/sonic_ax_impl/mibs/ietf/rfc1213.py @@ -1,5 +1,6 @@ import ipaddress import python_arptable +import socket from enum import unique, Enum from bisect import bisect_right @@ -673,3 +674,31 @@ class InterfacesMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.2'): # FIXME Placeholder ifSpecific = \ SubtreeMIBEntry('2.1.22', if_updater, ValueType.OBJECT_IDENTIFIER, lambda sub_id: ObjectIdentifier.null_oid()) + +class sysNameUpdater(MIBUpdater): + def __init__(self): + super().__init__() + self.db_conn = mibs.init_db() + self.hostname = socket.gethostname() + + def reinit_data(self): + self.db_conn.connect(self.db_conn.CONFIG_DB) + device_metadata = self.db_conn.get_all(self.db_conn.CONFIG_DB, "DEVICE_METADATA|localhost") + + if device_metadata and device_metadata.get('hostname'): + self.hostname = device_metadata['hostname'] + + def update_data(self): + return + + def get_sys_name(self): + """ + Subclass update interface information + """ + return self.hostname + + +class SysNameMIB(metaclass=MIBMeta, prefix='.1.3.6.1.2.1.1.5'): + updater = sysNameUpdater() + + sysName = MIBEntry('0', ValueType.OCTET_STRING, updater.get_sys_name) diff --git a/tests/mock_tables/config_db.json b/tests/mock_tables/config_db.json index a61777fea344..2d9dd54e07f8 100644 --- a/tests/mock_tables/config_db.json +++ b/tests/mock_tables/config_db.json @@ -14,5 +14,9 @@ "admin_status": "up", "alias": "mgmt2", "speed": 1000 + }, + "DEVICE_METADATA|localhost": { + "chassis_serial_number": "SAMPLETESTSN", + "hostname" : "test_hostname" } } diff --git a/tests/mock_tables/global_db/config_db.json b/tests/mock_tables/global_db/config_db.json index a61777fea344..40cdd212c049 100644 --- a/tests/mock_tables/global_db/config_db.json +++ b/tests/mock_tables/global_db/config_db.json @@ -14,5 +14,9 @@ "admin_status": "up", "alias": "mgmt2", "speed": 1000 + }, + "DEVICE_METADATA|localhost": { + "chassis_serial_number": "SAMPLETESTSN", + "hostname" : "namespace_hostname" } } diff --git a/tests/namespace/test_sysname.py b/tests/namespace/test_sysname.py new file mode 100644 index 000000000000..96c9024ba2e0 --- /dev/null +++ b/tests/namespace/test_sysname.py @@ -0,0 +1,44 @@ +import os +import sys +import importlib +from unittest import TestCase + +from ax_interface import ValueType +from ax_interface.pdu_implementations import GetPDU, GetNextPDU +from ax_interface.encodings import ObjectIdentifier +from ax_interface.constants import PduTypes +from ax_interface.pdu import PDU, PDUHeader +from ax_interface.mib import MIBTable +from sonic_ax_impl.mibs.ietf import rfc1213 +import tests.mock_tables.dbconnector + +class TestGetNextPDU(TestCase): + @classmethod + def setUpClass(cls): + tests.mock_tables.dbconnector.load_namespace_config() + importlib.reload(rfc1213) + cls.lut = MIBTable(rfc1213.SysNameMIB) + for updater in cls.lut.updater_instances: + updater.reinit_data() + updater.update_data() + + def test_getpdu_sysname(self): + oid = ObjectIdentifier(9, 0, 0, 0, (1, 3, 6, 1, 2, 1, 1, 5, 0)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + n = len(response.values) + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.OCTET_STRING) + self.assertEqual(str(value0.name), str(ObjectIdentifier(9, 0, 0, 0, (1, 3, 6, 1, 2, 1, 1, 5, 0)))) + self.assertEqual(str(value0.data), 'namespace_hostname') + + @classmethod + def tearDownClass(cls): + tests.mock_tables.dbconnector.clean_up_config() diff --git a/tests/test_sysname.py b/tests/test_sysname.py new file mode 100644 index 000000000000..b8bcaf2e153f --- /dev/null +++ b/tests/test_sysname.py @@ -0,0 +1,38 @@ +import os +import sys +from unittest import TestCase + +from unittest import TestCase + +from ax_interface import ValueType +from ax_interface.pdu_implementations import GetPDU, GetNextPDU +from ax_interface.encodings import ObjectIdentifier +from ax_interface.constants import PduTypes +from ax_interface.pdu import PDU, PDUHeader +from ax_interface.mib import MIBTable +from sonic_ax_impl.mibs.ietf import rfc1213 + +class TestGetNextPDU(TestCase): + @classmethod + def setUpClass(cls): + cls.lut = MIBTable(rfc1213.SysNameMIB) + for updater in cls.lut.updater_instances: + updater.reinit_data() + updater.update_data() + + def test_getpdu_sysname(self): + oid = ObjectIdentifier(9, 0, 0, 0, (1, 3, 6, 1, 2, 1, 1, 5, 0)) + get_pdu = GetPDU( + header=PDUHeader(1, PduTypes.GET, 16, 0, 42, 0, 0, 0), + oids=[oid] + ) + + encoded = get_pdu.encode() + response = get_pdu.make_response(self.lut) + print(response) + + n = len(response.values) + value0 = response.values[0] + self.assertEqual(value0.type_, ValueType.OCTET_STRING) + self.assertEqual(str(value0.name), str(ObjectIdentifier(9, 0, 0, 0, (1, 3, 6, 1, 2, 1, 1, 5, 0)))) + self.assertEqual(str(value0.data), 'test_hostname')