-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add utility function for creating SNMP sessions
This new function aids in creating nav.Snmp sessions based on ManagementProfile instances.
- Loading branch information
1 parent
a613588
commit af860f1
Showing
2 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# | ||
# Copyright (C) 2023 Sikt | ||
# | ||
# This file is part of Network Administration Visualized (NAV). | ||
# | ||
# NAV is free software: you can redistribute it and/or modify it under | ||
# the terms of the GNU General Public License version 3 as published by | ||
# the Free Software Foundation. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
# more details. You should have received a copy of the GNU General Public | ||
# License along with NAV. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
"""Helper functions to build SNMP sessions from NAV ManagementProfile instances""" | ||
from functools import partial | ||
from typing import Callable | ||
|
||
from nav.models.manage import Netbox, ManagementProfile | ||
from nav.Snmp import Snmp | ||
|
||
|
||
def get_snmp_session_for_profile(profile: ManagementProfile) -> Callable: | ||
"""Returns a nav.Snmp.Snmp constructor partially pre-configured with SNMP options | ||
from an SNMP management profile. | ||
Example usage: | ||
>>> netbox = Netbox.objects.get(id=1) | ||
>>> snmp = get_snmp_session_for_profile( | ||
... netbox.get_preferred_snmp_management_profile()) | ||
>>> session = snmp(netbox.ip) | ||
>>> session.get() | ||
b'Linux 16e2ac5c6456 6.1.60 #1-NixOS SMP PREEMPT_DYNAMIC Wed Oct 25 10:03:17 UTC 2023 x86_64' | ||
>>> | ||
""" | ||
if not profile.is_snmp: | ||
raise ValueError("Cannot create SNMP session from non-SNMP management profile") | ||
|
||
if profile.snmp_version < 3: | ||
kwargs = { | ||
"version": profile.configuration.get("version"), | ||
"community": profile.configuration.get("community"), | ||
} | ||
else: | ||
kwargs = { | ||
opt: profile.configuration.get(opt) or None | ||
for opt in ( | ||
"sec_level", | ||
"auth_protocol", | ||
"sec_name", | ||
"auth_password", | ||
"priv_protocol", | ||
"priv_password", | ||
) | ||
} | ||
kwargs["version"] = 3 | ||
|
||
return partial(Snmp, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# | ||
# Copyright (C) 2023 Sikt | ||
# | ||
# This file is part of Network Administration Visualized (NAV). | ||
# | ||
# NAV is free software: you can redistribute it and/or modify it under | ||
# the terms of the GNU General Public License version 3 as published by | ||
# the Free Software Foundation. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
# more details. You should have received a copy of the GNU General Public | ||
# License along with NAV. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
from unittest.mock import Mock | ||
|
||
import pytest | ||
|
||
from nav.Snmp import Snmp | ||
from nav.Snmp.profile import get_snmp_session_for_profile | ||
|
||
|
||
class TestGetSnmpSessionForProfile: | ||
def test_when_valid_snmpv2_profile_is_given_it_should_return_a_valid_snmp_partial( | ||
self, mock_snmpv2_profile | ||
): | ||
snmp = get_snmp_session_for_profile(mock_snmpv2_profile) | ||
assert callable(snmp) | ||
session = snmp("127.0.0.1") | ||
assert isinstance(session, Snmp) | ||
|
||
def test_when_valid_snmpv3_profile_is_given_it_should_return_a_valid_snmp_partial( | ||
self, mock_snmpv3_profile | ||
): | ||
snmp = get_snmp_session_for_profile(mock_snmpv3_profile) | ||
assert callable(snmp) | ||
session = snmp("127.0.0.1") | ||
assert isinstance(session, Snmp) | ||
|
||
conf = mock_snmpv3_profile.configuration | ||
assert session.sec_level.value == conf["sec_level"] | ||
assert session.auth_protocol.value == conf["auth_protocol"] | ||
assert session.sec_name == conf["sec_name"] | ||
assert session.auth_password == conf["auth_password"] | ||
|
||
def test_when_non_snmp_profile_is_given_it_should_raise_valueerror(self): | ||
profile = Mock(is_snmp=False) | ||
with pytest.raises(ValueError): | ||
get_snmp_session_for_profile(profile) | ||
|
||
|
||
@pytest.fixture | ||
def mock_snmpv2_profile(): | ||
profile = Mock(is_snmp=True, snmp_version=2) | ||
profile.configuration = { | ||
"version": "2c", | ||
"write": False, | ||
"community": "public", | ||
} | ||
return profile | ||
|
||
|
||
@pytest.fixture | ||
def mock_snmpv3_profile(): | ||
profile = Mock(is_snmp=True, snmp_version=3) | ||
profile.configuration = { | ||
"version": "3", | ||
"sec_level": "authNoPriv", | ||
"auth_protocol": "SHA", | ||
"sec_name": "foobar", | ||
"auth_password": "zaphodbeeblebrox", | ||
} | ||
return profile |