Skip to content

Commit d8987ba

Browse files
authored
Closes #43: Dont create empty changelog entries
2 parents d97dfcc + 1e1d43a commit d8987ba

File tree

4 files changed

+43
-43
lines changed

4 files changed

+43
-43
lines changed

netbox_config_diff/compliance/base.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,12 @@
88
from dcim.choices import DeviceStatusChoices
99
from dcim.models import Device, DeviceRole, Site
1010
from django.conf import settings
11-
from django.core.exceptions import ObjectDoesNotExist
1211
from django.db.models import Q
1312
from extras.scripts import MultiObjectVar, ObjectVar
1413
from jinja2.exceptions import TemplateError
1514
from netutils.config.compliance import diff_network_config
1615
from utilities.exceptions import AbortScript
1716

18-
from netbox_config_diff.models import ConfigCompliance
19-
2017
from .models import DeviceDataClass
2118
from .secrets import SecretsMixin
2219
from .utils import PLATFORM_MAPPING, CustomChoiceVar, exclude_lines, get_unified_diff
@@ -112,13 +109,7 @@ def validate_data(self, data: dict) -> Iterable[Device]:
112109
def update_in_db(self, devices: list[DeviceDataClass]) -> None:
113110
for device in devices:
114111
self.log_results(device)
115-
try:
116-
obj = ConfigCompliance.objects.get(device_id=device.pk)
117-
obj.snapshot()
118-
obj.update(**device.to_db())
119-
obj.save()
120-
except ObjectDoesNotExist:
121-
ConfigCompliance.objects.create(**device.to_db())
112+
device.send_to_db()
122113

123114
def log_results(self, device: DeviceDataClass) -> None:
124115
if device.error:

netbox_config_diff/compliance/models.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from scrapli import AsyncScrapli
55

66
from netbox_config_diff.choices import ConfigComplianceStatusChoices
7+
from netbox_config_diff.models import ConfigCompliance
78

89

910
@dataclass
@@ -18,21 +19,21 @@ class DeviceDataClass:
1819
exclude_regex: str | None = None
1920
rendered_config: str | None = None
2021
actual_config: str | None = None
21-
diff: str | None = None
22+
diff: str = ""
2223
missing: str | None = None
2324
extra: str | None = None
24-
error: str | None = None
25+
error: str = ""
2526
config_error: str | None = None
2627
auth_strict_key: bool = False
2728
transport: str = "asyncssh"
2829

29-
def __str__(self):
30+
def __str__(self) -> str:
3031
return self.name
3132

32-
def __hash__(self):
33+
def __hash__(self) -> int:
3334
return hash(self.name)
3435

35-
def to_scrapli(self):
36+
def to_scrapli(self) -> dict:
3637
return {
3738
"host": self.mgmt_ip,
3839
"auth_username": self.username,
@@ -78,13 +79,16 @@ def to_scrapli(self):
7879
},
7980
}
8081

81-
def to_db(self):
82+
def get_status(self) -> str:
8283
if self.error:
83-
status = ConfigComplianceStatusChoices.ERRORED
84+
return ConfigComplianceStatusChoices.ERRORED
8485
elif self.diff:
85-
status = ConfigComplianceStatusChoices.DIFF
86+
return ConfigComplianceStatusChoices.DIFF
8687
else:
87-
status = ConfigComplianceStatusChoices.COMPLIANT
88+
return ConfigComplianceStatusChoices.COMPLIANT
89+
90+
def to_db(self) -> dict:
91+
status = self.get_status()
8892

8993
return {
9094
"device_id": self.pk,
@@ -97,7 +101,17 @@ def to_db(self):
97101
"extra": self.extra or "",
98102
}
99103

100-
async def get_actual_config(self):
104+
def send_to_db(self) -> None:
105+
try:
106+
obj = ConfigCompliance.objects.get(device_id=self.pk)
107+
if obj.status != self.get_status():
108+
obj.update(commit=True, **self.to_db())
109+
elif obj.diff != self.diff or obj.error != self.error:
110+
obj.update(commit=True, **self.to_db())
111+
except ConfigCompliance.DoesNotExist:
112+
ConfigCompliance.objects.create(**self.to_db())
113+
114+
async def get_actual_config(self) -> None:
101115
if self.error is not None:
102116
return
103117
try:

netbox_config_diff/configurator/base.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from netbox_config_diff.configurator.exceptions import DeviceConfigurationError, DeviceValidationError
2020
from netbox_config_diff.configurator.utils import CustomLogger
2121
from netbox_config_diff.constants import ACCEPTABLE_DRIVERS
22-
from netbox_config_diff.models import ConfigCompliance
2322

2423
from .factory import AsyncScrapliCfg
2524

@@ -28,9 +27,9 @@ class Configurator(SecretsMixin):
2827
def __init__(self, devices: Iterable[Device], request: NetBoxFakeRequest) -> None:
2928
self.devices = devices
3029
self.request = request
31-
self.unprocessed_devices = set()
32-
self.processed_devices = set()
33-
self.failed_devices = set()
30+
self.unprocessed_devices: set[DeviceDataClass] = set()
31+
self.processed_devices: set[DeviceDataClass] = set()
32+
self.failed_devices: set[DeviceDataClass] = set()
3433
self.substitutes: dict[str, list] = {}
3534
self.logger = CustomLogger()
3635
self.connections: dict[str, AsyncScrapliCfgPlatform] = {}
@@ -109,13 +108,7 @@ def collect_diffs(self) -> None:
109108
@sync_to_async
110109
def update_diffs(self) -> None:
111110
for device in self.unprocessed_devices:
112-
try:
113-
obj = ConfigCompliance.objects.get(device_id=device.pk)
114-
obj.snapshot()
115-
obj.update(**device.to_db())
116-
obj.save()
117-
except ConfigCompliance.DoesNotExist:
118-
ConfigCompliance.objects.create(**device.to_db())
111+
device.send_to_db()
119112

120113
async def _collect_diffs(self) -> None:
121114
async with self.connection():

netbox_config_diff/models.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,18 @@ class ConfigCompliance(ChangeLoggingMixin, models.Model):
5454
class Meta:
5555
ordering = ("device",)
5656

57-
def __str__(self):
57+
def __str__(self) -> str:
5858
return self.device.name
5959

6060
def get_absolute_url(self):
6161
return reverse("plugins:netbox_config_diff:configcompliance", args=[self.pk])
6262

63-
def get_status_color(self):
63+
def get_status_color(self) -> str:
6464
return ConfigComplianceStatusChoices.colors.get(self.status)
6565

66-
def update(self, commit=False, **kwargs):
66+
def update(self, commit: bool = False, **kwargs) -> None:
67+
if commit:
68+
self.snapshot()
6769
for key, value in kwargs.items():
6870
setattr(self, key, value)
6971
if commit:
@@ -102,7 +104,7 @@ class PlatformSetting(NetBoxModel):
102104
class Meta:
103105
ordering = ("driver",)
104106

105-
def __str__(self):
107+
def __str__(self) -> str:
106108
return f"{self.platform} {self.driver}"
107109

108110
def get_absolute_url(self):
@@ -156,20 +158,20 @@ class ConfigurationRequest(JobsMixin, PrimaryModel):
156158
class Meta:
157159
ordering = ("-created",)
158160

159-
def __str__(self):
161+
def __str__(self) -> str:
160162
return f"CR #{self.pk}"
161163

162164
def get_absolute_url(self):
163165
return reverse("plugins:netbox_config_diff:configurationrequest", args=[self.pk])
164166

165-
def get_status_color(self):
167+
def get_status_color(self) -> str:
166168
return ConfigurationRequestStatusChoices.colors.get(self.status)
167169

168170
@property
169-
def finished(self):
171+
def finished(self) -> bool:
170172
return self.status in ConfigurationRequestStatusChoices.FINISHED_STATE_CHOICES
171173

172-
def delete(self, *args, **kwargs):
174+
def delete(self, *args, **kwargs) -> None:
173175
super().delete(*args, **kwargs)
174176

175177
queue = django_rq.get_queue(RQ_QUEUE_DEFAULT)
@@ -180,7 +182,7 @@ def delete(self, *args, **kwargs):
180182
except InvalidJobOperation:
181183
pass
182184

183-
def enqueue_job(self, request, job_name, schedule_at=None):
185+
def enqueue_job(self, request, job_name, schedule_at=None) -> Job:
184186
return Job.enqueue(
185187
import_string(f"netbox_config_diff.jobs.{job_name}"),
186188
name=f"{self} {job_name}",
@@ -190,7 +192,7 @@ def enqueue_job(self, request, job_name, schedule_at=None):
190192
schedule_at=schedule_at,
191193
)
192194

193-
def start(self, job: Job):
195+
def start(self, job: Job) -> None:
194196
"""
195197
Record the job's start time and update its status to "running."
196198
"""
@@ -201,7 +203,7 @@ def start(self, job: Job):
201203
self.status = ConfigurationRequestStatusChoices.RUNNING
202204
self.save()
203205

204-
def terminate(self, job: Job, status: str = ConfigurationRequestStatusChoices.COMPLETED):
206+
def terminate(self, job: Job, status: str = ConfigurationRequestStatusChoices.COMPLETED) -> None:
205207
job.terminate(status=status)
206208
self.status = status
207209
self.completed = timezone.now()
@@ -243,7 +245,7 @@ class Substitute(NetBoxModel):
243245
class Meta:
244246
ordering = ("name",)
245247

246-
def __str__(self):
248+
def __str__(self) -> str:
247249
return self.name
248250

249251
def get_absolute_url(self):

0 commit comments

Comments
 (0)