Skip to content

Commit d5d3fe8

Browse files
authored
Version 2.5.0 (#73)
* Closes #67: Add option default_desired_privilege_level (#68) * Closes #69: Fix logger in SecretsMixin (#71) * Closes #70: Add escapejs filter to diff template (#72) Co-authored-by: Clemens Knost
1 parent ae9e761 commit d5d3fe8

File tree

11 files changed

+58
-16
lines changed

11 files changed

+58
-16
lines changed

docs/changelog.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Changelog
22

3+
4+
## 2.5.0 (2024-06-30)
5+
6+
* [#67](https://github.com/miaow2/netbox-config-diff/issues/67) Add option `default_desired_privilege_level` to plugins variables (thanks to [@cknost](https://github.com/cknost))
7+
* [#69](https://github.com/miaow2/netbox-config-diff/issues/69) Fix logger in SecretsMixin
8+
* [#70](https://github.com/miaow2/netbox-config-diff/issues/80) Add `escapejs` filter to diff templates
9+
10+
## 2.4.0 (2024-05-12)
11+
12+
* [#63](https://github.com/miaow2/netbox-config-diff/issues/63) Generate patch commands necessary to bring a device into its intended configuration with [hier_config](https://github.com/netdevops/hier_config)
13+
14+
## 2.3.0 (2024-04-11)
15+
16+
* [#49](https://github.com/miaow2/netbox-config-diff/issues/49) Handle junipers templates with set commands
17+
* [#56](https://github.com/miaow2/netbox-config-diff/issues/56) Add support for NetBox 3.7
18+
* [#57](https://github.com/miaow2/netbox-config-diff/issues/57) Reverse columns in compliance diff
19+
320
## 2.2.0 (2024-02-06)
421

522
* [#47](https://github.com/miaow2/netbox-config-diff/issues/47) Move plugin to separete menu item in navbar and add tab for devices with compliance result

docs/secrets.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# Integration with NetBox secrets plugin
22

33
You can store credentials for devices authentification in NetBox secrets [plugin](https://github.com/Onemind-Services-LLC/netbox-secrets).
4-
5-
Read NetBox secrets docs for more info.
4+
Read NetBox secrets docs for more info.
65

76
In plugin variables define secrets roles for username (`USER_SECRET_ROLE`), password (`PASSWORD_SECRET_ROLE`) and
87
password (`SECOND_AUTH_SECRET_ROLE`) for Privileged EXEC mode.
@@ -21,4 +20,7 @@ PLUGINS_CONFIG = {
2120

2221
Script will find secrets with these roles attached to the device and use them as credentials.
2322

23+
Also you can define secret role for desired privilege level in plugins variable `DEFAULT_DESIRED_PRIVILEGE_LEVEL_ROLE`
24+
or can specify the desired privilege level itself in variable `DEFAULT_DESIRED_PRIVILEGE_LEVEL`.
25+
2426
If something goes wrong, then credentials from `PLUGINS_CONFIG` will be used.

netbox_config_diff/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
__author__ = "Artem Kotik"
44
__email__ = "[email protected]"
5-
__version__ = "2.4.0"
5+
__version__ = "2.5.0"
66

77

88
class ConfigDiffConfig(PluginConfig):

netbox_config_diff/compliance/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ def get_devices_with_rendered_configs(self, devices: Iterable[Device]) -> Iterat
130130
self.check_netbox_secrets()
131131
self.substitutes = {}
132132
for device in devices:
133-
username, password, auth_secondary = self.get_credentials(device)
133+
if self.data["data_source"]:
134+
username, password, auth_secondary, default_desired_privilege_level = None, None, None, None
135+
else:
136+
username, password, auth_secondary, default_desired_privilege_level = self.get_credentials(device)
134137
rendered_config = None
135138
error = None
136139
context_data = device.get_config_context()
@@ -159,6 +162,7 @@ def get_devices_with_rendered_configs(self, devices: Iterable[Device]) -> Iterat
159162
username=username,
160163
password=password,
161164
auth_secondary=auth_secondary,
165+
default_desired_privilege_level=default_desired_privilege_level,
162166
rendered_config=rendered_config,
163167
error=error,
164168
device=device,

netbox_config_diff/compliance/secrets.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ def get_master_key(self) -> None:
3434
self.master_key = sk.get_master_key(self.session_key)
3535
except Exception as e:
3636
if getattr(self, "logger"):
37-
self.logger.log_failure(f"Can't fetch master_key: {str(e)}")
37+
if getattr(self.logger, "log_failure"):
38+
self.logger.log_failure(f"Can't fetch master_key: {str(e)}")
39+
else:
40+
self.logger.error(f"Can't fetch master_key: {str(e)}")
3841
else:
3942
self.log_failure(f"Can't fetch master_key: {str(e)}")
4043

@@ -45,9 +48,9 @@ def get_secret(self, secret: "Secret") -> str | None:
4548
return None
4649
return secret.plaintext
4750

48-
def get_credentials(self, device: Device) -> tuple[str, str, str]:
51+
def get_credentials(self, device: Device) -> tuple[str, str, str, str]:
4952
if not self.netbox_secrets_installed:
50-
return self.username, self.password, self.auth_secondary
53+
return self.username, self.password, self.auth_secondary, self.default_desired_privilege_level
5154

5255
if secret := device.secrets.filter(role__name=self.user_role).first():
5356
username = value if (value := self.get_secret(secret)) else self.username
@@ -61,17 +64,29 @@ def get_credentials(self, device: Device) -> tuple[str, str, str]:
6164
auth_secondary = value if (value := self.get_secret(secret)) else self.auth_secondary
6265
else:
6366
auth_secondary = self.auth_secondary
67+
if secret := device.secrets.filter(role__name=self.default_desired_privilege_level_role).first():
68+
default_desired_privilege_level = (
69+
value if (value := self.get_secret(secret)) else self.default_desired_privilege_level
70+
)
71+
else:
72+
default_desired_privilege_level = self.default_desired_privilege_level
6473

65-
return username, password, auth_secondary
74+
return username, password, auth_secondary, default_desired_privilege_level
6675

6776
def check_netbox_secrets(self) -> None:
6877
if "netbox_secrets" in get_installed_plugins():
6978
self.get_master_key()
7079
self.user_role = get_plugin_config("netbox_config_diff", "USER_SECRET_ROLE")
7180
self.password_role = get_plugin_config("netbox_config_diff", "PASSWORD_SECRET_ROLE")
7281
self.auth_secondary_role = get_plugin_config("netbox_config_diff", "SECOND_AUTH_SECRET_ROLE")
82+
self.default_desired_privilege_level_role = get_plugin_config(
83+
"netbox_config_diff", "DEFAULT_DESIRED_PRIVILEGE_LEVEL_ROLE"
84+
)
7385
self.netbox_secrets_installed = True
7486

7587
self.username = get_plugin_config("netbox_config_diff", "USERNAME")
7688
self.password = get_plugin_config("netbox_config_diff", "PASSWORD")
7789
self.auth_secondary = get_plugin_config("netbox_config_diff", "AUTH_SECONDARY")
90+
self.default_desired_privilege_level = get_plugin_config(
91+
"netbox_config_diff", "DEFAULT_DESIRED_PRIVILEGE_LEVEL"
92+
)

netbox_config_diff/configurator/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def __init__(self, devices: Iterable[Device], request: NetBoxFakeRequest) -> Non
3737
def validate_devices(self) -> None:
3838
self.check_netbox_secrets()
3939
for device in self.devices:
40-
username, password, auth_secondary = self.get_credentials(device)
40+
username, password, auth_secondary, default_desired_privilege_level = self.get_credentials(device)
4141
if device.platform.platform_setting is None:
4242
self.logger.log_warning(f"Skipping {device}, add PlatformSetting for {device.platform} platform")
4343
elif device.platform.platform_setting.driver not in ACCEPTABLE_DRIVERS:
@@ -67,6 +67,7 @@ def validate_devices(self) -> None:
6767
username=username,
6868
password=password,
6969
auth_secondary=auth_secondary,
70+
default_desired_privilege_level=default_desired_privilege_level,
7071
rendered_config=rendered_config,
7172
error=error,
7273
)

netbox_config_diff/models/data_models.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class BaseDeviceDataClass:
1515
name: str
1616
mgmt_ip: str
1717
platform: str
18-
username: str
19-
password: str
18+
username: str | None
19+
password: str | None
2020
exclude_regex: str | None = None
2121
rendered_config: str | None = None
2222
actual_config: str | None = None
@@ -28,6 +28,7 @@ class BaseDeviceDataClass:
2828
config_error: str | None = None
2929
auth_strict_key: bool = False
3030
auth_secondary: str | None = None
31+
default_desired_privilege_level: str | None = None
3132
transport: str = "asyncssh"
3233

3334
def __str__(self) -> str:
@@ -41,6 +42,7 @@ def to_scrapli(self) -> dict:
4142
"platform": self.platform,
4243
"auth_strict_key": self.auth_strict_key,
4344
"auth_secondary": self.auth_secondary,
45+
"default_desired_privilege_level": self.default_desired_privilege_level,
4446
"transport": self.transport,
4547
"transport_options": {
4648
"asyncssh": {

netbox_config_diff/templates/netbox_config_diff/configcompliance/data.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ <h5 class="card-header">Diff</h5>
7070
stickyFileHeaders: false,
7171
drawFileList: false,
7272
};
73-
const jsonDiff = `{{ instance.diff|safe }}`;
73+
const jsonDiff = `{{ instance.diff|escapejs|safe }}`;
7474
var targetElement = document.getElementById('diffElement');
7575
var diff2htmlUi = new Diff2HtmlUI(targetElement, jsonDiff, configuration);
7676
diff2htmlUi.draw();

netbox_config_diff/templates/netbox_config_diff/inc/diff.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ <h5 class="card-header">{{ device_name }} - Diff</h5>
1717
stickyFileHeaders: false,
1818
drawFileList: false,
1919
};
20-
const jsonDiff = `{{ data|safe }}`;
20+
const jsonDiff = `{{ data|escapejs|safe }}`;
2121
var targetElement = document.getElementById('{{ device_name }}-diffElement');
2222
var diff2htmlUi = new Diff2HtmlUI(targetElement, jsonDiff, configuration);
2323
diff2htmlUi.draw();

requirements/base.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
hier-config==2.2.3
22
netutils==1.5.0
3-
scrapli[asyncssh]==2023.07.30
4-
scrapli-cfg==2023.07.30
5-
scrapli-community==2023.07.30
3+
scrapli[asyncssh]==2024.01.30
4+
scrapli-cfg==2024.01.30
5+
scrapli-community==2024.01.30

0 commit comments

Comments
 (0)