Skip to content

Commit f55bee8

Browse files
authored
snmpagent: modify entities to include fans under fabric module (#349)
With Modular Chassis, fans need not be present just in the fan drawers, but also in fabric modules. Currently, fan and sensor information of fabric modules is not accessible via SNMP. This patch set fixes that problem. - What I did Essentially, make fans under fabric modules accessible in a way we currently access fans under fan drawers. - How I did it Added a new cache updater, which keeps track of all the fans under fabric modules, so that they can be queried via SNMP. - How to verify it SNMP walk of chassis should display the fan information, if any, present under fabric modules. Added a unit test and also tested these changes manually on Internal machines. - Description for the changelog Other PR's of interest for this change: sonic-net/sonic-platform-daemons#601, sonic-net/sonic-mgmt#17686.
1 parent 6e0ff93 commit f55bee8

File tree

6 files changed

+102
-2
lines changed

6 files changed

+102
-2
lines changed

src/sonic_ax_impl/mibs/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ def psu_info_table(psu_name):
9696

9797
return "PSU_INFO" + TABLE_NAME_SEPARATOR_VBAR + psu_name
9898

99+
def chassis_module_table(module_name):
100+
"""
101+
:param module_name: module name
102+
:return chassis module table entry for this module
103+
"""
104+
return "CHASSIS_MODULE_TABLE" + TABLE_NAME_SEPARATOR_VBAR + module_name
99105

100106
def physical_entity_info_table(name):
101107
"""

src/sonic_ax_impl/mibs/ietf/physical_entity_sub_oid_generator.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
2 - Management
1717
5 - Fan Drawer
1818
6 - PSU
19+
7 - Fabric Card
1920
Device Type describes below:
2021
01 - PS
2122
02 - Fan
@@ -53,6 +54,7 @@
5354
MODULE_TYPE_MGMT = 2 * MODULE_TYPE_MULTIPLE
5455
MODULE_TYPE_FAN_DRAWER = 5 * MODULE_TYPE_MULTIPLE
5556
MODULE_TYPE_PSU = 6 * MODULE_TYPE_MULTIPLE
57+
MODULE_TYPE_FABRIC_CARD = 7 * MODULE_TYPE_MULTIPLE
5658
MODULE_TYPE_PORT = 1000000000
5759

5860
# Device Type Definition
@@ -120,6 +122,15 @@ def get_fan_drawer_sub_id(position):
120122
"""
121123
return (MODULE_TYPE_FAN_DRAWER + position * MODULE_INDEX_MULTIPLE, )
122124

125+
def get_fabric_card_sub_id(position):
126+
"""
127+
Returns sub OID for fabric card. Sub OID is calculated as follows:
128+
sub OID = MODULE_TYPE_FABRIC_CARD + position * MODULE_INDEX_MULTIPLE
129+
:param position: fabric card position
130+
:return: sub OID of the fabric card
131+
"""
132+
return (MODULE_TYPE_FABRIC_CARD + position * MODULE_INDEX_MULTIPLE, )
133+
123134
def get_fan_tachometers_sub_id(parent_id):
124135
"""
125136
Returns sub OID for fan tachometers. Sub OID is calculated as follows:

src/sonic_ax_impl/mibs/ietf/rfc2737.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .physical_entity_sub_oid_generator import get_fan_drawer_sub_id
1919
from .physical_entity_sub_oid_generator import get_fan_tachometers_sub_id
2020
from .physical_entity_sub_oid_generator import get_psu_sub_id
21+
from .physical_entity_sub_oid_generator import get_fabric_card_sub_id
2122
from .physical_entity_sub_oid_generator import get_psu_sensor_sub_id
2223
from .physical_entity_sub_oid_generator import get_transceiver_sub_id
2324
from .physical_entity_sub_oid_generator import get_transceiver_sensor_sub_id
@@ -928,6 +929,48 @@ def _update_psu_sensor_cache(self, psu_name, psu_sub_id, sensor_name):
928929
self.mib_updater.set_phy_contained_in(psu_current_sub_id, psu_sub_id)
929930
self.mib_updater.set_phy_fru(psu_current_sub_id, False)
930931

932+
@physical_entity_updater()
933+
class FabricCardCacheUpdater(PhysicalEntityCacheUpdater):
934+
KEY_PATTERN = mibs.chassis_module_table("FABRIC-CARD*")
935+
936+
def __init__(self, mib_updater):
937+
super(FabricCardCacheUpdater, self).__init__(mib_updater)
938+
939+
def get_key_pattern(self):
940+
return FabricCardCacheUpdater.KEY_PATTERN
941+
942+
def _update_entity_cache(self, fc_name):
943+
fc_info = Namespace.dbs_get_all(self.mib_updater.statedb, mibs.STATE_DB,
944+
mibs.chassis_module_table(fc_name))
945+
946+
if not fc_info:
947+
return
948+
949+
model, presence, serial, replaceable = get_db_data(fc_info, FanDrawerInfoDB)
950+
if presence.lower() != 'true':
951+
self._remove_entity_cache(fc_name)
952+
return
953+
954+
fc_relation_info = self.get_physical_relation_info(fc_name)
955+
if fc_relation_info:
956+
fc_position, fc_parent_name = get_db_data(fc_relation_info, PhysicalRelationInfoDB)
957+
fc_position = int(fc_position)
958+
fc_sub_id = get_fabric_card_sub_id(fc_position)
959+
self._add_entity_related_oid(fc_name, fc_sub_id)
960+
self.mib_updater.update_name_to_oid_map(fc_name, fc_sub_id)
961+
962+
# add fabric card to available OID list
963+
self.mib_updater.add_sub_id(fc_sub_id)
964+
self.mib_updater.set_phy_class(fc_sub_id, PhysicalClass.MODULE)
965+
self.mib_updater.set_phy_descr(fc_sub_id, fc_name)
966+
self.mib_updater.set_phy_name(fc_sub_id, fc_name)
967+
self.mib_updater.set_phy_parent_relative_pos(fc_sub_id, fc_position)
968+
self.mib_updater.set_phy_contained_in(fc_sub_id, fc_parent_name)
969+
if model and not is_null_str(model):
970+
self.mib_updater.set_phy_model_name(fc_sub_id, model)
971+
if serial and not is_null_str(serial):
972+
self.mib_updater.set_phy_serial_num(fc_sub_id, serial)
973+
self.mib_updater.set_phy_fru(fc_sub_id, replaceable)
931974

932975
@physical_entity_updater()
933976
class FanDrawerCacheUpdater(PhysicalEntityCacheUpdater):

src/sonic_ax_impl/mibs/ietf/rfc3433.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .physical_entity_sub_oid_generator import get_transceiver_sensor_sub_id
1515
from .physical_entity_sub_oid_generator import get_fan_drawer_sub_id
1616
from .physical_entity_sub_oid_generator import get_fan_sub_id
17+
from .physical_entity_sub_oid_generator import get_fabric_card_sub_id
1718
from .physical_entity_sub_oid_generator import get_fan_tachometers_sub_id
1819
from .physical_entity_sub_oid_generator import get_psu_sub_id
1920
from .physical_entity_sub_oid_generator import get_psu_sensor_sub_id
@@ -23,6 +24,7 @@
2324
NOT_AVAILABLE = 'N/A'
2425
CHASSIS_NAME_SUB_STRING = 'chassis'
2526
PSU_NAME_SUB_STRING = 'PSU'
27+
FABRIC_CARD_NAME_SUB_STRING = 'FABRIC-CARD'
2628
RJ45_PORT_TYPE = 'RJ45'
2729

2830
def is_null_empty_str(value):
@@ -536,6 +538,8 @@ def update_fan_sensor_data(self):
536538

537539
if PSU_NAME_SUB_STRING in fan_parent_name:
538540
fan_parent_sub_id = get_psu_sub_id(fan_parent_position)
541+
elif FABRIC_CARD_NAME_SUB_STRING in fan_parent_name:
542+
fan_parent_sub_id = get_fabric_card_sub_id(fan_parent_position)
539543
else:
540544
fan_parent_sub_id = get_fan_drawer_sub_id(fan_parent_position)
541545
else:

tests/test_rfc2737.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import pytest
66
from sonic_ax_impl.mibs.ietf.rfc2737 import PhysicalTableMIBUpdater
7-
7+
from sonic_ax_impl.mibs.ietf.rfc2737 import FabricCardCacheUpdater
88

99
if sys.version_info.major == 3:
1010
from unittest import mock
@@ -30,13 +30,15 @@ def test_PhysicalTableMIBUpdater_exception_in_reinit_data_wont_block_reinit_iter
3030
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanDrawerCacheUpdater.reinit_data') as mocked_fan_drawer_reinit_data,
3131
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanCacheUpdater.reinit_data') as mocked_fan_cache_reinit_data,
3232
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.ThermalCacheUpdater.reinit_data') as mocked_thermal_reinit_data,
33+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FabricCardCacheUpdater.reinit_data') as mocked_fc_reinit_data,
3334
mock.patch('sonic_ax_impl.mibs.cancel_redis_pubsub') as mocked_cancel_redis_pubsub):
3435
updater.reinit_data()
3536
mocked_xcvr_reinit_data.assert_called()
3637
mocked_psu_reinit_data.assert_called()
3738
mocked_fan_drawer_reinit_data.assert_called()
3839
mocked_fan_cache_reinit_data.assert_called()
3940
mocked_thermal_reinit_data.assert_called()
41+
mocked_fc_reinit_data.assert_called()
4042
mocked_cancel_redis_pubsub.assert_called()
4143
assert str(excinfo.value) == "[Exception('mocked error')]"
4244

@@ -53,13 +55,15 @@ def test_PhysicalTableMIBUpdater_exception_in_reinit_data_wont_block_reinit_iter
5355
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.PsuCacheUpdater.reinit_data') as mocked_psu_reinit_data,
5456
mock.patch(
5557
'sonic_ax_impl.mibs.ietf.rfc2737.FanDrawerCacheUpdater.reinit_data') as mocked_fan_drawer_reinit_data,
58+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FabricCardCacheUpdater.reinit_data') as mocked_fc_reinit_data,
5659
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanCacheUpdater.reinit_data') as mocked_fan_cache_reinit_data,
5760
mock.patch('sonic_ax_impl.mibs.cancel_redis_pubsub') as mocked_cancel_redis_pubsub):
5861
updater.reinit_data()
5962
mocked_xcvr_reinit_data.assert_called()
6063
mocked_psu_reinit_data.assert_called()
6164
mocked_fan_drawer_reinit_data.assert_called()
6265
mocked_fan_cache_reinit_data.assert_called()
66+
mocked_fc_reinit_data.assert_called()
6367
mocked_thermal_reinit_data.assert_called()
6468
mocked_cancel_redis_pubsub.assert_called()
6569
assert str(excinfo.value) == "[Exception('mocked error')]"
@@ -79,13 +83,15 @@ def test_PhysicalTableMIBUpdater_runtime_exc_in_reinit_data_wont_block_reinit_it
7983
'sonic_ax_impl.mibs.ietf.rfc2737.FanDrawerCacheUpdater.reinit_data') as mocked_fan_drawer_reinit_data,
8084
mock.patch(
8185
'sonic_ax_impl.mibs.ietf.rfc2737.FanCacheUpdater.reinit_data') as mocked_fan_cache_reinit_data,
86+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FabricCardCacheUpdater.reinit_data') as mocked_fc_reinit_data,
8287
mock.patch('sonic_ax_impl.mibs.cancel_redis_pubsub') as mocked_cancel_redis_pubsub):
8388
updater.reinit_data()
8489
mocked_thermal_reinit_data.assert_called()
8590
mocked_xcvr_reinit_data.assert_called()
8691
mocked_psu_reinit_data.assert_called()
8792
mocked_fan_drawer_reinit_data.assert_called()
8893
mocked_fan_cache_reinit_data.assert_called()
94+
mocked_fc_reinit_data.assert_called()
8995
mocked_cancel_redis_pubsub.assert_called()
9096
assert str(excinfo.value) == "[RuntimeError('mocked runtime error')]"
9197

@@ -102,13 +108,15 @@ def test_PhysicalTableMIBUpdater_runtime_exc_in_reinit_data_wont_block_reinit_it
102108
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanDrawerCacheUpdater.reinit_data') as mocked_fan_drawer_reinit_data,
103109
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanCacheUpdater.reinit_data') as mocked_fan_cache_reinit_data,
104110
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.ThermalCacheUpdater.reinit_data') as mocked_thermal_reinit_data,
111+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FabricCardCacheUpdater.reinit_data') as mocked_fc_reinit_data,
105112
mock.patch('sonic_ax_impl.mibs.cancel_redis_pubsub') as mocked_cancel_redis_pubsub):
106113
updater.reinit_data()
107114
mocked_xcvr_reinit_data.assert_called()
108115
mocked_psu_reinit_data.assert_called()
109116
mocked_fan_drawer_reinit_data.assert_called()
110117
mocked_fan_cache_reinit_data.assert_called()
111118
mocked_thermal_reinit_data.assert_called()
119+
mocked_fc_reinit_data.assert_called()
112120
mocked_cancel_redis_pubsub.assert_called()
113121
assert str(exc_info.value) == "[RuntimeError('mocked runtime error')]"
114122

@@ -127,12 +135,29 @@ def test_PhysicalTableMIBUpdater_multi_exception(self, mocked_xcvr_reinit_data,
127135
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.PsuCacheUpdater.reinit_data') as mocked_psu_reinit_data,
128136
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanDrawerCacheUpdater.reinit_data') as mocked_fan_drawer_reinit_data,
129137
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FanCacheUpdater.reinit_data') as mocked_fan_cache_reinit_data,
138+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.FabricCardCacheUpdater.reinit_data') as mocked_fc_reinit_data,
130139
mock.patch('sonic_ax_impl.mibs.cancel_redis_pubsub') as mocked_cancel_redis_pubsub):
131140
updater.reinit_data()
132141
mocked_xcvr_reinit_data.assert_called()
133142
mocked_psu_reinit_data.assert_called()
134143
mocked_fan_drawer_reinit_data.assert_called()
135144
mocked_fan_cache_reinit_data.assert_called()
145+
mocked_fc_reinit_data.assert_called()
136146
mocked_thermal_reinit_data.assert_called()
137147
mocked_cancel_redis_pubsub.assert_called()
138148
assert str(exc_info.value) == "[RuntimeError('mocked runtime error'), Exception('mocked error')]"
149+
150+
151+
class TestFabricCardCacheUpdater(TestCase):
152+
@mock.patch('sonic_ax_impl.mibs.Namespace.dbs_get_all', mock.MagicMock(return_value=({"model": "Model000", "presence": "True", "serial" : "Serial000", "is_replaceable" : "False"})))
153+
@mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.PhysicalEntityCacheUpdater.get_physical_relation_info', mock.MagicMock(return_value=({"position_in_parent" : 0, "parent_name" : "Chassis 1"})))
154+
def test_update_entity_cache(self):
155+
updater = PhysicalTableMIBUpdater()
156+
fc_updater = FabricCardCacheUpdater(updater)
157+
update_entity_cache = getattr(fc_updater, '_update_entity_cache')
158+
159+
with (mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.PhysicalTableMIBUpdater.set_phy_contained_in') as mocked_phy_contained_in,
160+
mock.patch('sonic_ax_impl.mibs.ietf.rfc2737.PhysicalTableMIBUpdater.set_phy_fru') as mocked_set_phy_fru):
161+
update_entity_cache('N/A')
162+
mocked_phy_contained_in.assert_called()
163+
mocked_set_phy_fru.assert_called()

tests/test_rfc3433.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,15 @@ def test_PhysicalSensorTableMIBUpdater_re_init_redis_exception(self):
3636
updater.reinit_connection()
3737

3838
# check re-init
39-
connect_all_dbs.assert_called()
39+
connect_all_dbs.assert_called()
40+
41+
@mock.patch('swsscommon.swsscommon.SonicV2Connector.get_all', mock.MagicMock(return_value=({"position_in_parent" : '0', "parent_name" : "FABRIC-CARD0"})))
42+
def test_PhysicalSensorTableMIBUpdater_fabriccard_update_fan_sensor_data(self):
43+
updater = PhysicalSensorTableMIBUpdater()
44+
updater.fan_sensor = ['FABRIC_MODULE|FAN']
45+
46+
with mock.patch('sonic_ax_impl.mibs.ietf.rfc3433.get_fabric_card_sub_id') as mocked_get_fc_subid:
47+
updater.update_fan_sensor_data()
48+
49+
# check fabric card subid function is called to get parent's sub id
50+
mocked_get_fc_subid.assert_called()

0 commit comments

Comments
 (0)