Skip to content

Commit

Permalink
Encryption handling test code
Browse files Browse the repository at this point in the history
  • Loading branch information
ktbyers committed Oct 10, 2024
1 parent def78da commit c8e9e66
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 27 deletions.
1 change: 1 addition & 0 deletions netmiko/cli_tools/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def obtain_devices(device_or_group: str) -> Dict[str, Dict[str, Any]]:


def update_device_params(params, username=None, password=None, secret=None):
"""Add username, password, and secret fields to params dictionary"""
if username:
params["username"] = username
if password:
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import pytest

TEST_ENCRYPTION_KEY = "boguskey"


@pytest.fixture
def set_encryption_key(monkeypatch):
"""Fixture to set a test encryption key"""

def _set_key(key=TEST_ENCRYPTION_KEY):
"""Inner function to set a test encryption key"""
monkeypatch.setenv("NETMIKO_TOOLS_KEY", key)
return key

return _set_key
85 changes: 58 additions & 27 deletions tests/unit/test_clitools_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,15 @@
from netmiko.cli_tools.helpers import ssh_conn, obtain_devices, update_device_params


TEST_ENCRYPTION_KEY = "boguskey"
BASE_YAML_PATH = Path(__file__).parent / "NETMIKO_YAML"


@pytest.fixture
def set_encryption_key(monkeypatch):
"""Fixture to set a test encryption key"""
monkeypatch.setenv("NETMIKO_TOOLS_KEY", TEST_ENCRYPTION_KEY)


@pytest.fixture
def mock_connecthandler():
with patch("netmiko.cli_tools.helpers.ConnectHandler") as mock:
yield mock


# @pytest.fixture
# def mock_load_netmiko_yml():
# with patch("helpers.load_netmiko_yml") as mock:
# yield mock
#
#
# @pytest.fixture
# def mock_decrypt_config():
# with patch("helpers.decrypt_config") as mock:
# yield mock


# @pytest.fixture
# def mock_get_encryption_key():
# with patch("helpers.get_encryption_key") as mock:
# yield mock


def test_ssh_conn_success(mock_connecthandler):
mock_net_connect = MagicMock()
mock_net_connect.send_command.return_value = "Command output"
Expand Down Expand Up @@ -70,12 +45,14 @@ def test_ssh_conn_failure(mock_connecthandler):
assert result == (device_name, ERROR_PATTERN)


@pytest.mark.parametrize("netmiko_yml", ["netmiko-cleartext.yml", "netmiko-encr.yml", "netmiko-encr-aes128.yml"])
@pytest.mark.parametrize(
"netmiko_yml",
["netmiko-cleartext.yml", "netmiko-encr.yml", "netmiko-encr-aes128.yml"],
)
def test_obtain_devices_all(netmiko_yml, monkeypatch, set_encryption_key):
yml_path = BASE_YAML_PATH / netmiko_yml
monkeypatch.setenv("NETMIKO_TOOLS_CFG", str(yml_path))

import pdbr; pdbr.set_trace()
result = obtain_devices("all")

assert len(result) == 7 # Total number of devices
Expand All @@ -96,3 +73,57 @@ def test_obtain_devices_all(netmiko_yml, monkeypatch, set_encryption_key):
assert result["den-asa"]["device_type"] == "cisco_asa"
assert result["den-asa"]["ip"] == "10.1.1.1"
assert result["den-asa"]["secret"] == "supersecretpass"


BASE_PARAMS = {"device_type": "cisco_ios", "host": "bogus.domain.com"}


@pytest.mark.parametrize(
"initial_params, update_args, expected_result",
[
(
{**BASE_PARAMS},
{"username": "admin", "password": "new_pass", "secret": "new_secret"},
{
**BASE_PARAMS,
"username": "admin",
"password": "new_pass",
"secret": "new_secret",
},
),
(
{**BASE_PARAMS, "username": "old_user"},
{"password": "new_pass"},
{**BASE_PARAMS, "username": "old_user", "password": "new_pass"},
),
(
{**BASE_PARAMS, "username": "user", "password": "pass"},
{"secret": "new_secret"},
{
**BASE_PARAMS,
"username": "user",
"password": "pass",
"secret": "new_secret",
},
),
(
{**BASE_PARAMS, "username": "user", "password": "pass", "secret": "secret"},
{},
{**BASE_PARAMS, "username": "user", "password": "pass", "secret": "secret"},
),
(
{**BASE_PARAMS, "username": "existing_user"},
{"username": "new_user"},
{
**BASE_PARAMS,
"username": "new_user",
},
),
],
)
def test_update_device_params(initial_params, update_args, expected_result):
result = update_device_params(initial_params, **update_args)
assert result == expected_result, f"Expected {expected_result}, but got {result}"
assert (
result is initial_params
), "Function should modify the original dictionary, not create a new one"
28 changes: 28 additions & 0 deletions tests/unit/test_encryption_hanlding.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
import os
from netmiko.encryption_handling import encrypt_value, decrypt_value, ENCRYPTION_PREFIX
from netmiko.encryption_handling import get_encryption_key


@pytest.mark.parametrize("encryption_type", ["fernet", "aes128"])
Expand Down Expand Up @@ -38,3 +40,29 @@ def test_encrypt_decrypt(encryption_type):

# Verify that the decrypted value matches the original
assert decrypted_value == original_value


def test_get_encryption_key_success(set_encryption_key):

# Use fixture to mock setting the environment variable
key = "a_test_key"
set_encryption_key(key)

# Call the function
result = get_encryption_key()

# Check if the result matches the set key
assert result == key.encode(), "The retrieved key should match the set key"


def test_get_encryption_key_missing():
# Ensure the environment variable is not set
if "NETMIKO_TOOLS_KEY" in os.environ:
del os.environ["NETMIKO_TOOLS_KEY"]

# Check if the function raises a ValueError
with pytest.raises(ValueError) as excinfo:
get_encryption_key()

# Optionally, check the error message
assert "Encryption key not found" in str(excinfo.value)

0 comments on commit c8e9e66

Please sign in to comment.