Skip to content

Commit

Permalink
Add tab for devices with their config compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
miaow2 committed Jan 28, 2024
1 parent 1a3a4a7 commit 04b6655
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("dcim", "0181_rename_device_role_device_role"),
("netbox_config_diff", "0007_configurationrequest"),
]

operations = [
migrations.AlterField(
model_name="configcompliance",
name="device",
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="config_compliance",
to="dcim.device",
),
),
]
2 changes: 1 addition & 1 deletion netbox_config_diff/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ConfigCompliance(AbsoluteURLMixin, ChangeLoggingMixin, models.Model):
device = models.OneToOneField(
to="dcim.Device",
on_delete=models.CASCADE,
related_name="config_compliamce",
related_name="config_compliance",
)
status = models.CharField(
max_length=50,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,81 +1,13 @@
{% extends "netbox_config_diff/configcompliance/base.html" %}
{% load static %}
{% extends "generic/object.html" %}
{% load buttons %}
{% load perms %}

{% block content %}
<div class="row mb-3">
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">{{ object|meta:"verbose_name"|bettertitle }}</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Device</th>
<td>{{ object.device|linkify }}</td>
</tr>
<tr>
<th scope="row">Status</th>
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
</tr>
</table>
</div>
</div>
{% block controls %}
<div class="controls">
<div class="control-group">
{% if request.user|can_delete:object %}
{% delete_button object %}
{% endif %}
</div>
{% if object.error %}
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">Error</h5>
<div class="card-body">
<pre class="block">{{ object.error }}</pre>
</div>
</div>
</div>
{% endif %}
</div>
{% if object.diff %}
<div class="row mb-3">
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Diff</h5>
<div class="card-body" id="diffElement"></div>
</div>
</div>
</div>
{% endif %}
{% endblock content %}

{% block javascript %}
<script type="text/javascript" src="{% static 'netbox_config_diff/diff2html-ui.min.js' %}"></script>
<script type="text/javascript">
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
const colorMode = localStorage.getItem("netbox-color-mode");
if (colorMode === 'dark') {
link.href = `{% static 'netbox_config_diff/diff2html.dark.min.css' %}`
} else {
link.href = `{% static 'netbox_config_diff/diff2html.min.css' %}`
};
document.head.appendChild(link);
document.addEventListener('DOMContentLoaded', () => {
var configuration = {
drawFileList: false,
fileListToggle: false,
fileListStartVisible: false,
fileContentToggle: false,
matching: 'lines',
outputFormat: 'side-by-side',
synchronisedScroll: true,
highlight: true,
renderNothingWhenEmpty: false,
stickyFileHeaders: false,
drawFileList: false,
};
const jsonDiff = `{{ object.diff|safe }}`;
var targetElement = document.getElementById('diffElement');
var diff2htmlUi = new Diff2HtmlUI(targetElement, jsonDiff, configuration);
diff2htmlUi.draw();
document.querySelector(".d2h-file-header").remove();
diff2htmlUi.highlightCode();
});
</script>
{% endblock javascript %}
{% endblock controls %}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "netbox_config_diff/configcompliance/base.html" %}
{% extends "netbox_config_diff/configcompliance.html" %}

{% block title %}{{ object }} - {{ header }}{% endblock %}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{% extends base_template %}
{% load static %}

{% block content %}
<div class="row mb-3">
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">{{ instance|meta:"verbose_name"|bettertitle }}</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Device</th>
<td>{{ instance.device|linkify }}</td>
</tr>
<tr>
<th scope="row">Status</th>
<td>{% badge instance.get_status_display bg_color=instance.get_status_color %}</td>
</tr>
</table>
</div>
</div>
</div>
{% if instance.error %}
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">Error</h5>
<div class="card-body">
<pre class="block">{{ instance.error }}</pre>
</div>
</div>
</div>
{% endif %}
</div>
{% if instance.diff %}
<div class="row mb-3">
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Diff</h5>
<div class="card-body" id="diffElement"></div>
</div>
</div>
</div>
{% endif %}
{% endblock content %}

{% block javascript %}
<script type="text/javascript" src="{% static 'netbox_config_diff/diff2html-ui.min.js' %}"></script>
<script type="text/javascript">
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
const colorMode = localStorage.getItem("netbox-color-mode");
if (colorMode === 'dark') {
link.href = `{% static 'netbox_config_diff/diff2html.dark.min.css' %}`
} else {
link.href = `{% static 'netbox_config_diff/diff2html.min.css' %}`
};
document.head.appendChild(link);
document.addEventListener('DOMContentLoaded', () => {
var configuration = {
drawFileList: false,
fileListToggle: false,
fileListStartVisible: false,
fileContentToggle: false,
matching: 'lines',
outputFormat: 'side-by-side',
synchronisedScroll: true,
highlight: true,
renderNothingWhenEmpty: false,
stickyFileHeaders: false,
drawFileList: false,
};
const jsonDiff = `{{ instance.diff|safe }}`;
var targetElement = document.getElementById('diffElement');
var diff2htmlUi = new Diff2HtmlUI(targetElement, jsonDiff, configuration);
diff2htmlUi.draw();
document.querySelector(".d2h-file-header").remove();
diff2htmlUi.highlightCode();
});
</script>
{% endblock javascript %}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% extends "netbox_config_diff/configcompliance/base.html" %}
{% extends "netbox_config_diff/configcompliance.html" %}

{% block title %}{{ object }} - Missing/Extra{% endblock %}

Expand Down
42 changes: 41 additions & 1 deletion netbox_config_diff/views/compliance.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dcim.models import Device
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect, render
from django.utils.translation import gettext as _
from netbox.views import generic
from utilities.views import ViewTab, register_model_view
Expand Down Expand Up @@ -51,6 +52,14 @@ def get_extra_context(self, request, instance):
@register_model_view(ConfigCompliance)
class ConfigComplianceView(generic.ObjectView):
queryset = ConfigCompliance.objects.all()
base_template = "netbox_config_diff/configcompliance.html"
template_name = "netbox_config_diff/configcompliance/data.html"

def get_extra_context(self, request, instance):
return {
"instance": instance,
"base_template": self.base_template,
}


@register_model_view(ConfigCompliance, "rendered-config")
Expand Down Expand Up @@ -113,6 +122,37 @@ def get(self, request, **kwargs):
)


@register_model_view(Device, "config_compliance", "config-compliance")
class ConfigComplianceDeviceView(generic.ObjectView):
queryset = Device.objects.all()
base_template = "dcim/device/base.html"
template_name = "netbox_config_diff/configcompliance/data.html"
tab = ViewTab(
label=_("Config Compliance"),
weight=2110,
badge=lambda obj: 1 if hasattr(obj, "config_compliance") else 0,
hide_if_empty=True,
)

def get(self, request, **kwargs):
instance = self.get_object(**kwargs)

if not hasattr(instance, "config_compliance"):
return redirect("dcim:device", pk=instance.pk)

return render(
request,
self.get_template_name(),
{
"object": instance,
"instance": instance.config_compliance,
"tab": self.tab,
"base_template": self.base_template,
**self.get_extra_context(request, instance),
},
)


class ConfigComplianceListView(generic.ObjectListView):
queryset = ConfigCompliance.objects.prefetch_related("device")
filterset = ConfigComplianceFilterSet
Expand Down

0 comments on commit 04b6655

Please sign in to comment.