Skip to content

Commit 36b9c39

Browse files
Merge pull request #53 from SWR-MoIP/52-add-support-for-snmp-global-setting-assignment-by-label-in-inventory-app
Enhance Inventory App: Add Support to Manage and Assign Global SNMP Settings
2 parents da80a42 + 98b011c commit 36b9c39

8 files changed

Lines changed: 708 additions & 0 deletions

File tree

src/videoipath_automation_tool/apps/inventory/app/app.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
from videoipath_automation_tool.apps.inventory.app.get_device import InventoryGetDeviceMixin
1111
from videoipath_automation_tool.apps.inventory.inventory_api import InventoryAPI
1212
from videoipath_automation_tool.apps.inventory.model.drivers import CustomSettings, CustomSettingsType, DriverLiteral
13+
from videoipath_automation_tool.apps.inventory.model.global_snmp_config import SnmpConfiguration
1314
from videoipath_automation_tool.apps.inventory.model.inventory_device import InventoryDevice
1415
from videoipath_automation_tool.apps.inventory.model.inventory_device_configuration_compare import (
1516
InventoryDeviceComparison,
1617
)
1718
from videoipath_automation_tool.apps.inventory.model.inventory_discovered_device import DiscoveredInventoryDevice
19+
from videoipath_automation_tool.connector.models.response_rpc import ResponseRPC
1820
from videoipath_automation_tool.connector.vip_connector import VideoIPathConnector
1921
from videoipath_automation_tool.validators.device_id import validate_device_id
2022

@@ -349,6 +351,83 @@ def parse_configuration(config: dict) -> InventoryDevice:
349351
"""
350352
return InventoryDevice.parse_configuration(config)
351353

354+
# --- Global SNMP Configuration Helpers ---
355+
def get_global_snmp_config_id_by_label(self, label: str) -> Optional[str | List[str]]:
356+
"""Method to get the global SNMP configuration id by label.
357+
Note: If multiple SNMP configurations with the same label exist, a list of ids is returned.
358+
359+
Args:
360+
label (str): Label of the SNMP configuration
361+
362+
Returns:
363+
Optional[str | List[str]]: SNMP configuration id, None if not found, List of ids if multiple configurations with the same label exist
364+
"""
365+
return self._inventory_api.get_global_snmp_config_id_by_label(label=label)
366+
367+
def get_global_snmp_config_label_by_id(self, snmp_config_id: str) -> Optional[str]:
368+
"""Method to get the global SNMP configuration label by id.
369+
370+
Args:
371+
snmp_config_id (str): SNMP configuration id
372+
373+
Returns:
374+
Optional[str]: SNMP configuration label, None if not found
375+
"""
376+
return self._inventory_api.get_global_snmp_config_label_by_id(snmp_config_id=snmp_config_id)
377+
378+
def get_all_global_snmp_config_ids(self) -> dict[str, str]:
379+
"""Method to list all global SNMP configuration ids with their labels.
380+
381+
Returns:
382+
dict: {snmp_config_id: snmp_config_label}
383+
"""
384+
return self._inventory_api.get_all_global_snmp_config_ids()
385+
386+
# --- Global SNMP Configuration CRUD Methods ---
387+
def get_global_snmp_config(self, snmp_config_id: str) -> SnmpConfiguration:
388+
"""Method to get a global SNMP configuration by id from VideoIPath-Inventory
389+
390+
Args:
391+
snmp_config_id (str): SNMP configuration id
392+
393+
Returns:
394+
GlobalSnmpConfig: Global SNMP configuration object
395+
"""
396+
return self._inventory_api.get_global_snmp_config(snmp_config_id=snmp_config_id)
397+
398+
def add_global_snmp_config(self, snmp_config: SnmpConfiguration) -> SnmpConfiguration:
399+
"""Method to add a new global SNMP configuration
400+
401+
Args:
402+
snmp_config (SnmpConfiguration): SNMP configuration object to add
403+
404+
Returns:
405+
SnmpConfiguration: Added SNMP configuration object
406+
"""
407+
return self._inventory_api.add_global_snmp_config(snmp_config=snmp_config)
408+
409+
def update_global_snmp_config(self, snmp_config: SnmpConfiguration) -> SnmpConfiguration:
410+
"""Method to update a global SNMP configuration
411+
412+
Args:
413+
snmp_config (SnmpConfiguration): SNMP configuration object to update
414+
415+
Returns:
416+
SnmpConfiguration: Updated SNMP configuration object
417+
"""
418+
return self._inventory_api.update_global_snmp_config(snmp_config=snmp_config)
419+
420+
def remove_global_snmp_config(self, snmp_config_id: str) -> ResponseRPC:
421+
"""Method to remove a global SNMP configuration by id from VideoIPath-Inventory
422+
423+
Args:
424+
snmp_config_id (str): SNMP configuration id
425+
426+
Returns:
427+
ResponseRPC: Response object
428+
"""
429+
return self._inventory_api.remove_global_snmp_config(snmp_config_id=snmp_config_id)
430+
352431
# --- Deprecated Methods ---
353432
@deprecated(
354433
"This method is deprecated and will be removed in future versions.",

src/videoipath_automation_tool/apps/inventory/inventory_api.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
)
1414
from videoipath_automation_tool.apps.inventory.model.device_status import DeviceStatus
1515
from videoipath_automation_tool.apps.inventory.model.drivers import CustomSettingsType, DriverLiteral
16+
from videoipath_automation_tool.apps.inventory.model.global_snmp_config import SnmpConfiguration
17+
from videoipath_automation_tool.apps.inventory.model.global_snmp_request_rpc import SnmpRequestRpc
1618
from videoipath_automation_tool.apps.inventory.model.inventory_device import InventoryDevice
1719
from videoipath_automation_tool.apps.inventory.model.inventory_discovered_device import DiscoveredInventoryDevice
1820
from videoipath_automation_tool.apps.inventory.model.inventory_request_rpc import InventoryRequestRpc
@@ -664,6 +666,169 @@ def get_discovered_device(self, discovered_device_id: str) -> DiscoveredInventor
664666
response.data["status"]["devman"]["discoveredDevices"]["_items"][0]
665667
)
666668

669+
# --- Global SNMP Configuration Helpers ---
670+
def get_global_snmp_config_id_by_label(self, label: str) -> Optional[str | List[str]]:
671+
"""Method to get the global SNMP configuration id by label.
672+
Note: If multiple SNMP configurations with the same label exist, a list of ids is returned.
673+
674+
Args:
675+
label (str): Label of the SNMP configuration
676+
677+
Returns:
678+
Optional[str | List[str]]: SNMP configuration id, None if not found, List of ids if multiple configurations with the same label exist
679+
"""
680+
if not label:
681+
raise ValueError("Label must not be empty.")
682+
683+
escaped_label = urllib.parse.quote(label, safe="")
684+
url = f"/rest/v2/data/config/system/snmp/*/* where descriptor.label='{escaped_label}' /*"
685+
response = self.vip_connector.rest.get(url)
686+
if response.data and response.data["config"]["system"]["snmp"]["session"]:
687+
matches = response.data["config"]["system"]["snmp"]["session"]
688+
if len(matches) == 1:
689+
return list(matches.keys())[0]
690+
elif len(matches) > 1:
691+
self._logger.warning(
692+
f"Multiple SNMP configurations found with label '{label}''. Returning all matching ids."
693+
)
694+
return list(matches.keys())
695+
return None
696+
697+
def get_global_snmp_config_label_by_id(self, snmp_config_id: str) -> Optional[str]:
698+
"""Method to get the global SNMP configuration label by id.
699+
700+
Args:
701+
snmp_config_id (str): SNMP configuration id
702+
703+
Returns:
704+
Optional[str]: SNMP configuration label, None if not found
705+
"""
706+
if not snmp_config_id:
707+
raise ValueError("SNMP configuration id must not be empty.")
708+
709+
url = f"/rest/v2/data/config/system/snmp/session/{snmp_config_id}/descriptor/label"
710+
response = self.vip_connector.rest.get(url, node_check=False)
711+
if response.data and response.data["config"]["system"]["snmp"]["session"]:
712+
if snmp_config_id in response.data["config"]["system"]["snmp"]["session"]:
713+
return response.data["config"]["system"]["snmp"]["session"][snmp_config_id]["descriptor"]["label"]
714+
return None
715+
716+
def get_all_global_snmp_config_ids(self) -> dict[str, str]:
717+
"""Method to list all global SNMP configuration ids with their labels.
718+
719+
Returns:
720+
dict: {snmp_config_id: snmp_config_label}
721+
"""
722+
url = "/rest/v2/data/config/system/snmp/*/*/descriptor/label"
723+
response = self.vip_connector.rest.get(url)
724+
if not response.data:
725+
raise ValueError("Response data is empty.")
726+
727+
snmp_configs = response.data["config"]["system"]["snmp"]["session"]
728+
return {
729+
snmp_config_id: snmp_config["descriptor"]["label"] for snmp_config_id, snmp_config in snmp_configs.items()
730+
}
731+
732+
# --- Global SNMP Configuration CRUD Methods ---
733+
def get_global_snmp_config(self, snmp_config_id: str) -> SnmpConfiguration:
734+
"""Method to get a global SNMP configuration by id from VideoIPath-Inventory
735+
736+
Args:
737+
snmp_config_id (str): SNMP configuration id
738+
739+
Returns:
740+
GlobalSnmpConfig: Global SNMP configuration object
741+
"""
742+
if not snmp_config_id:
743+
raise ValueError("SNMP configuration id must not be empty.")
744+
745+
url = f"/rest/v2/data/config/system/snmp/session/{snmp_config_id}/**"
746+
response = self.vip_connector.rest.get(url)
747+
if not response.data:
748+
raise ValueError("Response data is empty.")
749+
750+
return SnmpConfiguration.parse_from_dict(response.data["config"]["system"]["snmp"]["session"])
751+
752+
def add_global_snmp_config(self, snmp_config: SnmpConfiguration) -> SnmpConfiguration:
753+
"""Method to add a new global SNMP configuration
754+
755+
Args:
756+
snmp_config (SnmpConfiguration): SNMP configuration object to add
757+
758+
Returns:
759+
SnmpConfiguration: Added SNMP configuration object
760+
"""
761+
if not snmp_config.id:
762+
raise ValueError("SNMP configuration id must be set.")
763+
764+
self._logger.debug(f"Adding new global SNMP configuration with id '{snmp_config.id}'.")
765+
766+
existing_configs_label = self.get_global_snmp_config_label_by_id(snmp_config.id)
767+
if existing_configs_label is not None:
768+
raise ValueError(f"SNMP configuration with id '{snmp_config.id}' already exists. Please update it instead.")
769+
770+
body = SnmpRequestRpc()
771+
body.add(snmp_config)
772+
773+
response = self.vip_connector.rpc.post("/api/updateSnmpConfig", body=body)
774+
775+
if response.header.status != "OK":
776+
raise ValueError(f"Failed to add global SNMP configuration. Error: {response}")
777+
778+
return self.get_global_snmp_config(snmp_config_id=snmp_config.id)
779+
780+
def update_global_snmp_config(self, snmp_config: SnmpConfiguration) -> SnmpConfiguration:
781+
"""Method to update a global SNMP configuration
782+
783+
Args:
784+
snmp_config (SnmpConfiguration): SNMP configuration object to update
785+
786+
Returns:
787+
SnmpConfiguration: Updated SNMP configuration object
788+
"""
789+
if not snmp_config.id:
790+
raise ValueError("SNMP configuration id must be set.")
791+
792+
self._logger.debug(f"Updating global SNMP configuration with id '{snmp_config.id}'.")
793+
794+
existing_configs_label = self.get_global_snmp_config_label_by_id(snmp_config.id)
795+
if existing_configs_label is None:
796+
raise ValueError(f"SNMP configuration with id '{snmp_config.id}' does not exist. Please add it first.")
797+
798+
body = SnmpRequestRpc()
799+
body.update(snmp_config)
800+
801+
response = self.vip_connector.rpc.post("/api/updateSnmpConfig", body=body)
802+
803+
if response.header.status != "OK":
804+
raise ValueError(f"Failed to update global SNMP configuration. Error: {response}")
805+
806+
return self.get_global_snmp_config(snmp_config_id=snmp_config.id)
807+
808+
def remove_global_snmp_config(self, snmp_config_id: str) -> ResponseRPC:
809+
"""Method to remove a global SNMP configuration by id from VideoIPath-Inventory
810+
811+
Args:
812+
snmp_config_id (str): SNMP configuration id
813+
814+
Returns:
815+
ResponseRPC: Response object
816+
"""
817+
if not snmp_config_id:
818+
raise ValueError("SNMP configuration id must be set.")
819+
820+
self._logger.debug(f"Removing global SNMP configuration with id '{snmp_config_id}'.")
821+
822+
body = SnmpRequestRpc()
823+
body.remove(snmp_config_id)
824+
825+
response = self.vip_connector.rpc.post("/api/updateSnmpConfig", body=body)
826+
827+
if response.header.status != "OK":
828+
raise ValueError(f"Failed to remove global SNMP configuration. Error: {response}")
829+
830+
return response
831+
667832
# --- Deprecated Methods ---
668833
@deprecated(
669834
"The method `fetch_device_ids_list` is deprecated and will be removed in a future release. ",

0 commit comments

Comments
 (0)