From e7d3c19b58421587360d74036955ba107b5b3945 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 10:18:02 -0400 Subject: [PATCH 01/10] Removed UserActions from admin --- netbox/extras/admin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/netbox/extras/admin.py b/netbox/extras/admin.py index 2093db31a..c5aec6732 100644 --- a/netbox/extras/admin.py +++ b/netbox/extras/admin.py @@ -19,8 +19,3 @@ class TopologyMapAdmin(admin.ModelAdmin): prepopulated_fields = { 'slug': ['name'], } - - -@admin.register(UserAction) -class UserActionAdmin(admin.ModelAdmin): - list_display = ['user', 'action', 'content_type', 'object_id', 'message'] From bddd9b6f392553d0fd435b7054025b27f099f902 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 10:53:32 -0400 Subject: [PATCH 02/10] Fixed typo --- netbox/templates/secrets/inc/private_key_modal.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/templates/secrets/inc/private_key_modal.html b/netbox/templates/secrets/inc/private_key_modal.html index c60823973..5ab5400c3 100644 --- a/netbox/templates/secrets/inc/private_key_modal.html +++ b/netbox/templates/secrets/inc/private_key_modal.html @@ -3,7 +3,7 @@ +{% include 'inc/graphs_modal.html' %} +{% endblock %} + +{% block javascript %} + {% endblock %} diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 18658f593..9d9da6a18 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -327,19 +327,7 @@ {% endif %} - - - +{% include 'inc/graphs_modal.html' %} {% include 'secrets/inc/private_key_modal.html' %} {% endblock %} diff --git a/netbox/templates/dcim/site.html b/netbox/templates/dcim/site.html index 749482cd6..8c5e8130d 100644 --- a/netbox/templates/dcim/site.html +++ b/netbox/templates/dcim/site.html @@ -145,18 +145,7 @@ - - +{% include 'inc/graphs_modal.html' %} {% endblock %} {% block javascript %} diff --git a/netbox/templates/inc/graphs_modal.html b/netbox/templates/inc/graphs_modal.html new file mode 100644 index 000000000..29eaf18bf --- /dev/null +++ b/netbox/templates/inc/graphs_modal.html @@ -0,0 +1,11 @@ + From 4cbf09e0e1558e8fe74dbee238aa3ffe2ae80eb4 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 11:45:47 -0400 Subject: [PATCH 06/10] Improved ExpandableNameField help_text --- netbox/utilities/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py index f392ae931..7ad41697e 100644 --- a/netbox/utilities/forms.py +++ b/netbox/utilities/forms.py @@ -158,7 +158,8 @@ class ExpandableNameField(forms.CharField): def __init__(self, *args, **kwargs): super(ExpandableNameField, self).__init__(*args, **kwargs) if not self.help_text: - self.help_text = 'Numeric ranges are supported for bulk creation.' + self.help_text = 'Numeric ranges are supported for bulk creation.
'\ + 'Example: ge-0/0/[0-47]' def to_python(self, value): if re.search(EXPANSION_PATTERN, value): From 0b66b547a37722d87c4843e88c6ffa63c849719a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 12:56:36 -0400 Subject: [PATCH 07/10] Fixed double top border on component template tables --- netbox/dcim/tables.py | 8 ++++---- netbox/project-static/css/base.css | 14 ++++++++++---- .../dcim/inc/devicetype_component_table.html | 4 +--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index c754b0296..3a8f364ef 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -145,7 +145,7 @@ class ConsolePortTemplateTable(tables.Table): empty_text = "None" show_header = False attrs = { - 'class': 'table table-hover panel-body', + 'class': 'table table-hover', } @@ -158,7 +158,7 @@ class ConsoleServerPortTemplateTable(tables.Table): empty_text = "None" show_header = False attrs = { - 'class': 'table table-hover panel-body', + 'class': 'table table-hover', } @@ -171,7 +171,7 @@ class PowerPortTemplateTable(tables.Table): empty_text = "None" show_header = False attrs = { - 'class': 'table table-hover panel-body', + 'class': 'table table-hover', } @@ -184,7 +184,7 @@ class PowerOutletTemplateTable(tables.Table): empty_text = "None" show_header = False attrs = { - 'class': 'table table-hover panel-body', + 'class': 'table table-hover', } diff --git a/netbox/project-static/css/base.css b/netbox/project-static/css/base.css index 89fd6f0b7..f44fd1a24 100644 --- a/netbox/project-static/css/base.css +++ b/netbox/project-static/css/base.css @@ -258,16 +258,22 @@ ul.rack_near_face li.empty:hover a { .dark_gray:hover { background-color: #2c3e50; } /* Misc */ -.panel table>thead>tr>th { - border-bottom: 0; +.panel table { + margin-bottom: 0; } -ul.nav-tabs, ul.nav-pills { - margin-bottom: 20px; +.panel .table th { + border-bottom-width: 1px; +} +.panel table tr.even:first-child td { + border-top: 0; } .panel .list-group { max-height: 400px; overflow: auto; } +ul.nav-tabs, ul.nav-pills { + margin-bottom: 20px; +} /* Fix progress bar margin inside table cells */ td .progress { margin-bottom: 0; diff --git a/netbox/templates/dcim/inc/devicetype_component_table.html b/netbox/templates/dcim/inc/devicetype_component_table.html index 3c8913dc6..55bed30e9 100644 --- a/netbox/templates/dcim/inc/devicetype_component_table.html +++ b/netbox/templates/dcim/inc/devicetype_component_table.html @@ -22,8 +22,6 @@
{{ title }}
- - {% render_table table table_template|default:'table.html' %} -
+ {% render_table table 'table.html' %} {% endif %} From 13e095770cbeb7a6886f2b30688915ad871cf023 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 12:58:41 -0400 Subject: [PATCH 08/10] Drafted documentation for extras --- docs/extras.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 docs/extras.md diff --git a/docs/extras.md b/docs/extras.md new file mode 100644 index 000000000..7144804db --- /dev/null +++ b/docs/extras.md @@ -0,0 +1,58 @@ +

Extras

+ +This section entails features of NetBox which are not crucial to its primary functions, but that provide additional value. + +[TOC] + +# Export Templates + +NetBox allows users to define custom templates that can be used when exporting objects. To create an export template, navigate to Extras > Export Templates under the admin interface. + +Each export template is associated with a certain type of object. For instance, if you create an export template for VLANs, your custom template will appear under the "Export" button on the VLANs list. + +Export templates are written in [Django's template language](https://docs.djangoproject.com/en/1.9/ref/templates/language/), which is very similar to Jinja2. The list of objects returned from the database is stored in the `queryset` variable. Typically, you'll want to iterate through this list using a for loop. + +A MIME type and file extension can optionally be defined for each export template. The default MIME type is `text/plain`. + +## Example + +Here's an example device export template that will generate a simple Nagios configuration from a list of devices. + +``` +{% for d in queryset %}{% if d.status and d.primary_ip %}define host{ + use generic-switch + host_name {{ d.name }} + address {{ d.primary_ip.address.ip }} +} +{% endif %}{% endfor %} +``` + +The generated output will look something like this: + +``` +define host{ + use generic-switch + host_name switch1 + address 192.0.2.1 +} +define host{ + use generic-switch + host_name switch2 + address 192.0.2.2 +} +define host{ + use generic-switch + host_name switch3 + address 192.0.2.3 +} +``` + +# Graphs + +NetBox does not generate graphs itself. This feature allows you to embed contextual graphs from an external resources inside certain NetBox views. Each embedded graph must be defined with the following parameters: + +* **Type:** Interface, provider, or site. This determines where the graph will be displayed. +* **Weight:** Determines the order in which graphs are displayed (lower weights are displayed first). Graphs with equal weights will be ordered alphabetically by name. +* **Name:** The title to display above the graph. +* **Source URL:** The source of the image to be embedded. The associated object will be available as a template variable named `obj`. +* **Link URL (optional):** A URL to which the graph will be linked. The associated object will be available as a template variable named `obj`. From 0c8e9e582577552edea6d78fc3327ca55748b34b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 14:00:29 -0400 Subject: [PATCH 09/10] Downgrade to pydot-1.0.2 to fix unknown graph rendering error --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e6961f333..8987863a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,6 @@ paramiko==2.0.0 psycopg2==2.6.1 py-gfm==0.1.3 pycrypto==2.6.1 -pydot==1.1.0 +pydot==1.0.2 sqlparse==0.1.19 xmltodict==0.10.2 From d83d0b66b04899daec855cbf1057b41db2c8ee04 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 24 Jun 2016 14:01:57 -0400 Subject: [PATCH 10/10] Catch exceptions on graph generation --- netbox/extras/api/views.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 800863922..2436de401 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -84,14 +84,19 @@ class TopologyMapView(APIView): # Add all connections to the graph devices = Device.objects.filter(*(device_superset,)) - connections = InterfaceConnection.objects.filter(interface_a__device__in=devices, interface_b__device__in=devices) + connections = InterfaceConnection.objects.filter(interface_a__device__in=devices, + interface_b__device__in=devices) for c in connections: edge = pydot.Edge(c.interface_a.device.name, c.interface_b.device.name) graph.add_edge(edge) # Write the image to disk and return topo_file = tempfile.NamedTemporaryFile() - graph.write(topo_file.name, format='png') + try: + graph.write(topo_file.name, format='png') + except: + return HttpResponse("There was an error generating the requested graph. Ensure that the GraphViz " + "executables have been installed correctly.") response = HttpResponse(FileWrapper(topo_file), content_type='image/png') topo_file.close()