From a0f89a89e9fc3c5f24824306a09246a63986b994 Mon Sep 17 00:00:00 2001 From: "Jamie (Bear) Murphy" <1613241+ITJamie@users.noreply.github.com> Date: Mon, 4 Nov 2024 23:34:21 +0000 Subject: [PATCH] changelog extensions --- .devcontainer/Dockerfile | 8 ++-- .devcontainer/devcontainer.json | 16 ++++++-- .gitignore | 2 + netbox_changelog_diff_plugin/__init__.py | 6 ++- .../commands/create_changelog_summaries.py} | 35 ++++++++++------ .../migrations/0001_initial.py | 40 +++++++++++++++++++ .../0002_alter_changelogsummary_changelog.py | 24 +++++++++++ netbox_changelog_diff_plugin/models.py | 19 +++++---- netbox_changelog_diff_plugin/tables.py | 17 +++++++- pyproject.toml | 2 +- 10 files changed, 135 insertions(+), 34 deletions(-) rename netbox_changelog_diff_plugin/{commands.py => management/commands/create_changelog_summaries.py} (63%) create mode 100644 netbox_changelog_diff_plugin/migrations/0001_initial.py create mode 100644 netbox_changelog_diff_plugin/migrations/0002_alter_changelogsummary_changelog.py diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9ba2f5a..c32dd9e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,12 +1,10 @@ FROM mcr.microsoft.com/devcontainers/python:3 + + +# Run the commands in the Dockerfile RUN python -m pip install --upgrade pip \ && python -m pip install 'flit>=3.8.0' ENV FLIT_ROOT_INSTALL=1 -COPY pyproject.toml . -RUN touch README.md \ - && mkdir -p src/python_package \ - && python -m flit install --only-deps --deps develop \ - && rm -r pyproject.toml README.md src diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c4cf1ea..18b4640 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -19,9 +19,9 @@ "ms-python.flake8", "ms-python.black-formatter", "ms-vsliveshare.vsliveshare", - "ryanluker.vscode-coverage-gutters", - "bungcip.better-toml", - "GitHub.copilot" + "ryanluker.vscode-coverage-gutters" + // "bungcip.better-toml" + // "GitHub.copilot" ], "settings": { "python.defaultInterpreterPath": "/usr/local/bin/python", @@ -40,5 +40,13 @@ } } }, - "onCreateCommand": "pre-commit install-hooks" + "features": { + "ghcr.io/itsmechlark/features/postgresql:1": { + "version": "16" + }, + "ghcr.io/itsmechlark/features/redis-server:1": { + "version": "latest" + } + } } + diff --git a/.gitignore b/.gitignore index fa871cf..0cbed51 100644 --- a/.gitignore +++ b/.gitignore @@ -277,3 +277,5 @@ dmypy.json # Cython debug symbols cython_debug/ + +netbox-src diff --git a/netbox_changelog_diff_plugin/__init__.py b/netbox_changelog_diff_plugin/__init__.py index 48a16de..0aa9558 100644 --- a/netbox_changelog_diff_plugin/__init__.py +++ b/netbox_changelog_diff_plugin/__init__.py @@ -2,7 +2,7 @@ __author__ = """Jamie Murphy""" __email__ = "git@jam.ie" -__version__ = "0.2.1" +__version__ = "0.3.0" from netbox.plugins import PluginConfig @@ -18,6 +18,10 @@ class ChangeLogDiffConfig(PluginConfig): "change_log_format": "yaml", "hide_native_diff": False, } + def ready(self): + super().ready() + from netbox_changelog_diff_plugin.tables import register_changelog + register_changelog() config = ChangeLogDiffConfig diff --git a/netbox_changelog_diff_plugin/commands.py b/netbox_changelog_diff_plugin/management/commands/create_changelog_summaries.py similarity index 63% rename from netbox_changelog_diff_plugin/commands.py rename to netbox_changelog_diff_plugin/management/commands/create_changelog_summaries.py index 2238b37..2639f1c 100644 --- a/netbox_changelog_diff_plugin/commands.py +++ b/netbox_changelog_diff_plugin/management/commands/create_changelog_summaries.py @@ -1,6 +1,6 @@ from django.core.management.base import BaseCommand -from extras.models import ObjectChange -from .models import ChangeLogSummary +from core.models import ObjectChange +from netbox_changelog_diff_plugin.models import ChangeLogSummary class Command(BaseCommand): help = 'Creates ChangeLogSummary objects for ObjectChanges that do not have one' @@ -10,38 +10,47 @@ def handle(self, *args, **options): object_changes = ObjectChange.objects.filter( action='update' ).exclude( - id__in=ChangeLogSummary.objects.values_list('changelog_id', flat=True) + id__in=ChangeLogSummary.objects.values_list('changelog', flat=True) ) + # for change in object_changes: + # print(f"Creating ChangeLogSummary for {change}") + # self.stdout.write( + # self.style.SUCCESS(f'Successfully created {change.id} change') + # ) count = 0 for change in object_changes: summary = [] + if change.prechange_data and change.postchange_data: pre_keys = set(change.prechange_data.keys()) post_keys = set(change.postchange_data.keys()) - + # Find added keys added_keys = post_keys - pre_keys for key in added_keys: summary.append(f"Added {key}") - + # Find removed keys removed_keys = pre_keys - post_keys for key in removed_keys: summary.append(f"Removed {key}") - + # Check for updated values in common keys common_keys = pre_keys & post_keys for key in common_keys: if change.prechange_data[key] != change.postchange_data[key]: summary.append(f"Updated {key}") - - ChangeLogSummary.objects.create( + summary_msg = ", ".join(summary) if summary else "No changes detected" + print(f"summary: `{summary_msg}` for change id: {change.id}") + obj, created = ChangeLogSummary.objects.get_or_create( changelog=change, - summary=", ".join(summary) if summary else "No changes detected" + defaults={ + "summary": summary_msg + } ) - count += 1 + # count += 1 - self.stdout.write( - self.style.SUCCESS(f'Successfully created {count} new changelog summaries') - ) + # self.stdout.write( + # self.style.SUCCESS(f'Successfully created {count} new changelog summaries') + # ) diff --git a/netbox_changelog_diff_plugin/migrations/0001_initial.py b/netbox_changelog_diff_plugin/migrations/0001_initial.py new file mode 100644 index 0000000..fd6920a --- /dev/null +++ b/netbox_changelog_diff_plugin/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# Generated by Django 5.0.9 on 2024-11-04 22:09 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("core", "0012_job_object_type_optional"), + ] + + operations = [ + migrations.CreateModel( + name="ChangeLogSummary", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("summary", models.TextField()), + ( + "changelog", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="human_summary", + to="core.objectchange", + ), + ), + ], + options={ + "verbose_name": "Changelog Summary", + "verbose_name_plural": "Changelog Summaries", + }, + ), + ] diff --git a/netbox_changelog_diff_plugin/migrations/0002_alter_changelogsummary_changelog.py b/netbox_changelog_diff_plugin/migrations/0002_alter_changelogsummary_changelog.py new file mode 100644 index 0000000..f6fe399 --- /dev/null +++ b/netbox_changelog_diff_plugin/migrations/0002_alter_changelogsummary_changelog.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0.9 on 2024-11-04 23:19 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0012_job_object_type_optional"), + ("netbox_changelog_diff_plugin", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="changelogsummary", + name="changelog", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="human_summary", + to="core.objectchange", + ), + ), + ] diff --git a/netbox_changelog_diff_plugin/models.py b/netbox_changelog_diff_plugin/models.py index 21ba258..1081411 100644 --- a/netbox_changelog_diff_plugin/models.py +++ b/netbox_changelog_diff_plugin/models.py @@ -1,16 +1,19 @@ from django.db import models from django.urls import reverse from netbox.models import NetBoxModel +# from netbox.core.models import ObjectChange -class ChangeLogSummary(NetBoxModel): + +class ChangeLogSummary(models.Model): """Model to store human-readable summaries of changelogs""" - - changelog = models.ForeignKey( - to='extras.ObjectChange', + + changelog = models.OneToOneField( + to='core.ObjectChange', on_delete=models.CASCADE, - related_name='summaries' + related_name='human_summary', + unique=True ) - + summary = models.TextField( help_text="Human readable summary of the changes made" ) @@ -18,10 +21,10 @@ class ChangeLogSummary(NetBoxModel): class Meta: verbose_name = "Changelog Summary" verbose_name_plural = "Changelog Summaries" - ordering = ['-changelog__time'] + # ordering = ['-id'] def __str__(self): - return f"Summary for change {self.changelog.id}" + return f"{self.summary}" def get_absolute_url(self): return reverse('plugins:netbox_changelog_diff_plugin:changelogsummary', args=[self.pk]) diff --git a/netbox_changelog_diff_plugin/tables.py b/netbox_changelog_diff_plugin/tables.py index af145f7..e034314 100644 --- a/netbox_changelog_diff_plugin/tables.py +++ b/netbox_changelog_diff_plugin/tables.py @@ -1,2 +1,15 @@ -import django_tables2 as tables -from netbox.tables import NetBoxTable, ChoiceFieldColumn +import django_tables2 +from django.utils.translation import gettext_lazy as _ + +from .models import ChangeLogSummary +from core.tables.change_logging import ObjectChangeTable +from utilities.tables import register_table_column + +mycol_2 = django_tables2.Column( + verbose_name=_('Change Summary'), + accessor=django_tables2.A('human_summary'), + default="- -" +) + +def register_changelog(): + register_table_column(mycol_2, 'human_summary', ObjectChangeTable) diff --git a/pyproject.toml b/pyproject.toml index eb74120..fe57779 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "netbox-changelog-diff-plugin" -version = "0.2.1" +version = "0.3.0" authors = [ {name = "Jamie Murphy", email = "git@jam.ie"}, ]