From f0dc6fadb2d0b2f75eea39b3437e505aff59a59f Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Mon, 17 Jul 2023 09:01:55 -0500 Subject: [PATCH 1/6] Changes backup_file to be conditional --- .../plugins/tasks/dispatcher/default.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index 46c2941..7d5cafb 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -76,10 +76,11 @@ def get_config( logger.log_debug("Substitute lines from configuration based on `substitute_lines` definition") running_config = sanitize_config(running_config, substitute_lines) - make_folder(os.path.dirname(backup_file)) + if backup_file: + make_folder(os.path.dirname(backup_file)) - with open(backup_file, "w", encoding="utf8") as filehandler: - filehandler.write(running_config) + with open(backup_file, "w", encoding="utf8") as filehandler: + filehandler.write(running_config) return Result(host=task.host, result={"config": running_config}) @staticmethod @@ -330,10 +331,11 @@ def get_config( logger.log_debug("Substitute lines from configuration based on `substitute_lines` definition") running_config = sanitize_config(running_config, substitute_lines) - make_folder(os.path.dirname(backup_file)) + if backup_file: + make_folder(os.path.dirname(backup_file)) - with open(backup_file, "w", encoding="utf8") as filehandler: - filehandler.write(running_config) + with open(backup_file, "w", encoding="utf8") as filehandler: + filehandler.write(running_config) return Result(host=task.host, result={"config": running_config}) @staticmethod From 5c17c96e5b8c38f4993ce94a668b19dd658fcd0b Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 19 Jul 2023 10:51:22 -0500 Subject: [PATCH 2/6] Moves provision_config to default napalm driver --- .../plugins/tasks/dispatcher/default.py | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index 2310200..3e037a5 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -276,6 +276,51 @@ def _save_file(logger, backup_file: str, _running_config: str) -> None: with open(backup_file, "w", encoding="utf8") as filehandler: filehandler.write(_running_config) + @staticmethod + def provision_config( + task: Task, + logger, + obj, + config: str, + ) -> Result: + """Push candidate configuration to the device. + + Args: + task (Task): Nornir Task. + logger (NornirLogger): Custom NornirLogger object to reflect job_results (via Nautobot Jobs) and Python logger. + obj (Device): A Nautobot Device Django ORM object instance. + config (str): The candidate config. + + Raises: + NornirNautobotException: Authentication error. + NornirNautobotException: Timeout error. + NornirNautobotException: Other exception. + + Returns: + Result: Nornir Result object with a dict as a result containing the running configuration + { "config: } + """ + logger.log_success(obj, "Config provision starting") + # Sending None to napalm_configure for revert_in will disable it, so we don't want a default value. + revert_in = os.getenv("NORNIR_NAUTOBOT_REVERT_IN_SECONDS") + if revert_in is not None: + revert_in = int(revert_in) + + try: + push_result = task.run( + task=napalm_configure, + configuration=config, + replace=True, + revert_in=revert_in, + ) + except NornirSubTaskError as exc: + logger.log_failure(obj, f"Failed with an unknown issue. `{exc.result.exception}`") + raise NornirNautobotException() + + logger.log_success(obj, f"result: {push_result[0].result}, changed: {push_result.changed}") + logger.log_success(obj, "Config provision ended") + return Result(host=task.host, result={"changed": push_result.changed, "result": push_result[0].result}) + class NetmikoNautobotNornirDriver(NautobotNornirDriver): """Default collection of Nornir Tasks based on Netmiko.""" @@ -338,48 +383,3 @@ def get_config( with open(backup_file, "w", encoding="utf8") as filehandler: filehandler.write(running_config) return Result(host=task.host, result={"config": running_config}) - - @staticmethod - def provision_config( - task: Task, - logger, - obj, - config: str, - ) -> Result: - """Push candidate configuration to the device. - - Args: - task (Task): Nornir Task. - logger (NornirLogger): Custom NornirLogger object to reflect job_results (via Nautobot Jobs) and Python logger. - obj (Device): A Nautobot Device Django ORM object instance. - config (str): The candidate config. - - Raises: - NornirNautobotException: Authentication error. - NornirNautobotException: Timeout error. - NornirNautobotException: Other exception. - - Returns: - Result: Nornir Result object with a dict as a result containing the running configuration - { "config: } - """ - logger.log_success(obj, "Config provision starting") - # Sending None to napalm_configure for revert_in will disable it, so we don't want a default value. - revert_in = os.getenv("NORNIR_NAUTOBOT_REVERT_IN_SECONDS") - if revert_in is not None: - revert_in = int(revert_in) - - try: - push_result = task.run( - task=napalm_configure, - configuration=config, - replace=True, - revert_in=revert_in, - ) - except NornirSubTaskError as exc: - logger.log_failure(obj, f"Failed with an unknown issue. `{exc.result.exception}`") - raise NornirNautobotException() - - logger.log_success(obj, f"result: {push_result[0].result}, changed: {push_result.changed}") - logger.log_success(obj, "Config provision ended") - return Result(host=task.host, result={"changed": push_result.changed, "result": push_result[0].result}) From be4f72e4aaab99bec791222e1017034bfbb44cca Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 19 Jul 2023 10:52:02 -0500 Subject: [PATCH 3/6] Adds merge_config method --- .../plugins/tasks/dispatcher/default.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index 3e037a5..c1386b8 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -321,6 +321,51 @@ def provision_config( logger.log_success(obj, "Config provision ended") return Result(host=task.host, result={"changed": push_result.changed, "result": push_result[0].result}) + @staticmethod + def merge_config( + task: Task, + logger, + obj, + config: str, + ) -> Result: + """Send configuration to merge on the device. + + Args: + task (Task): Nornir Task. + logger (NornirLogger): Custom NornirLogger object to reflect job_results (via Nautobot Jobs) and Python logger. + obj (Device): A Nautobot Device Django ORM object instance. + config (str): The config set. + + Raises: + NornirNautobotException: Authentication error. + NornirNautobotException: Timeout error. + NornirNautobotException: Other exception. + + Returns: + Result: Nornir Result object with a dict as a result containing the running configuration + { "config: } + """ + logger.log_success(obj, "Config merge starting") + # Sending None to napalm_configure for revert_in will disable it, so we don't want a default value. + revert_in = os.getenv("NORNIR_NAUTOBOT_REVERT_IN_SECONDS") + if revert_in is not None: + revert_in = int(revert_in) + + try: + push_result = task.run( + task=napalm_configure, + configuration=config, + replace=False, + revert_in=revert_in, + ) + except NornirSubTaskError as exc: + logger.log_failure(obj, f"Failed with an unknown issue. `{exc.result.exception}`") + raise NornirNautobotException() + + logger.log_success(obj, f"result: {push_result[0].result}, changed: {push_result.changed}") + logger.log_success(obj, "Config merge ended") + return Result(host=task.host, result={"changed": push_result.changed, "result": push_result[0].result}) + class NetmikoNautobotNornirDriver(NautobotNornirDriver): """Default collection of Nornir Tasks based on Netmiko.""" From 95a895a9e61b2904dade0401ac7de64157362cb1 Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Wed, 19 Jul 2023 14:57:21 -0500 Subject: [PATCH 4/6] Fixes copy pasta docstring --- nornir_nautobot/plugins/tasks/dispatcher/default.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index c1386b8..60aa70c 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -297,8 +297,7 @@ def provision_config( NornirNautobotException: Other exception. Returns: - Result: Nornir Result object with a dict as a result containing the running configuration - { "config: } + Result: Nornir Result object with a dict as a result containing what changed and the result of the push. """ logger.log_success(obj, "Config provision starting") # Sending None to napalm_configure for revert_in will disable it, so we don't want a default value. @@ -342,8 +341,7 @@ def merge_config( NornirNautobotException: Other exception. Returns: - Result: Nornir Result object with a dict as a result containing the running configuration - { "config: } + Result: Nornir Result object with a dict as a result containing what changed and the result of the push. """ logger.log_success(obj, "Config merge starting") # Sending None to napalm_configure for revert_in will disable it, so we don't want a default value. From 0b657af3bd45e73d969b716cc697613ceb1860d4 Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Tue, 25 Jul 2023 14:27:11 -0500 Subject: [PATCH 5/6] Replaces provision_config with replace_config --- nornir_nautobot/plugins/tasks/dispatcher/default.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nornir_nautobot/plugins/tasks/dispatcher/default.py b/nornir_nautobot/plugins/tasks/dispatcher/default.py index 60aa70c..8fa481c 100644 --- a/nornir_nautobot/plugins/tasks/dispatcher/default.py +++ b/nornir_nautobot/plugins/tasks/dispatcher/default.py @@ -1,6 +1,7 @@ """default driver for the network_importer.""" # pylint: disable=raise-missing-from,too-many-arguments +import logging import os import socket from typing import Optional @@ -27,6 +28,9 @@ from nornir_nautobot.utils.helpers import make_folder +_logger = logging.getLogger(__name__) + + class NautobotNornirDriver: """Default collection of Nornir Tasks based on Napalm.""" @@ -276,8 +280,15 @@ def _save_file(logger, backup_file: str, _running_config: str) -> None: with open(backup_file, "w", encoding="utf8") as filehandler: filehandler.write(_running_config) + def provision_config(self, *args, **kwargs): + """This method is being deprecated. Please use replace_config instead.""" + _logger.warning( + "WARNING: The method 'provision_config()' will be removed in the next major release. Please use 'replace_config()' instead." + ) + return self.replace_config(*args, **kwargs) + @staticmethod - def provision_config( + def replace_config( task: Task, logger, obj, From f3417a84f55b76b482d2cfe602b34e2b146d32e7 Mon Sep 17 00:00:00 2001 From: Joe Wesch Date: Thu, 10 Aug 2023 13:09:57 -0500 Subject: [PATCH 6/6] Release v2.6.0 --- .github/CODEOWNERS | 2 +- docs/dev/CHANGELOG.md | 5 +++++ pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3fb561a..00d0dd6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ # Default owner(s) of all files in this repository -* @FragmentedPacket @jvanderaa @jmcgill298 @itdependsnetworks \ No newline at end of file +* @jvanderaa @jmcgill298 @itdependsnetworks \ No newline at end of file diff --git a/docs/dev/CHANGELOG.md b/docs/dev/CHANGELOG.md index 0f82c52..b1d3653 100644 --- a/docs/dev/CHANGELOG.md +++ b/docs/dev/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v2.6.0 + +- (#96) Changes backup_file to be conditional for get_config +- (#98) Adds merge_config method + ## v2.5.0 - (#93) Updates Nornir-Netmiko to 1.0.0 release diff --git a/pyproject.toml b/pyproject.toml index 47dd9c7..0382b0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nornir-nautobot" -version = "2.5.0" +version = "2.6.0" description = "Nornir Nautobot" authors = ["Network to Code, LLC "] readme = "README.md"