From a01c9ff379172eb855ab4e3d9767137307222d62 Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Fri, 29 Sep 2017 13:22:42 -0400 Subject: [PATCH 01/25] Minor LDAP documentation formatting cleanup --- docs/installation/ldap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation/ldap.md b/docs/installation/ldap.md index bb1618e32..3cbc0d32c 100644 --- a/docs/installation/ldap.md +++ b/docs/installation/ldap.md @@ -55,7 +55,7 @@ LDAP_IGNORE_CERT_ERRORS = True ## User Authentication !!! info - When using Windows Server, `2012 AUTH_LDAP_USER_DN_TEMPLATE` should be set to None. + When using Windows Server 2012, `AUTH_LDAP_USER_DN_TEMPLATE` should be set to None. ```python from django_auth_ldap.config import LDAPSearch @@ -79,7 +79,7 @@ AUTH_LDAP_USER_ATTR_MAP = { # User Groups for Permissions !!! Info - When using Microsoft Active Directory, Support for nested Groups can be activated by using `GroupOfNamesType()` instead of `NestedGroupOfNamesType()` for AUTH_LDAP_GROUP_TYPE. + When using Microsoft Active Directory, Support for nested Groups can be activated by using `GroupOfNamesType()` instead of `NestedGroupOfNamesType()` for `AUTH_LDAP_GROUP_TYPE`. ```python from django_auth_ldap.config import LDAPSearch, GroupOfNamesType From 109fff0fa6c12c8ed3732664616b536a6c7d5e16 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 10:59:39 -0400 Subject: [PATCH 02/25] Reorganized the docs --- docs/index.md | 3 ++- docs/{shell/intro.md => miscellaneous/shell.md} | 0 mkdocs.yml | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) rename docs/{shell/intro.md => miscellaneous/shell.md} (100%) diff --git a/docs/index.md b/docs/index.md index a661b5e0e..2e8c8b3dc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,6 +6,7 @@ NetBox is an open source web application designed to help manage and document co * **Equipment racks** - Organized by group and site * **Devices** - Types of devices and where they are installed * **Connections** - Network, console, and power connections among devices +* **Virtualization** - Virtual machines and clusters * **Data circuits** - Long-haul communications circuits and providers * **Secrets** - Encrypted storage of sensitive credentials @@ -46,7 +47,7 @@ NetBox is built on the [Django](https://djangoproject.com/) Python framework and | HTTP Service | nginx or Apache | | WSGI Service | gunicorn or uWSGI | | Application | Django/Python | -| Database | PostgreSQL | +| Database | PostgreSQL 9.4+ | # Getting Started diff --git a/docs/shell/intro.md b/docs/miscellaneous/shell.md similarity index 100% rename from docs/shell/intro.md rename to docs/miscellaneous/shell.md diff --git a/mkdocs.yml b/mkdocs.yml index e3ac9f50b..430a05ac7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -25,10 +25,9 @@ pages: - 'Authentication': 'api/authentication.md' - 'Working with Secrets': 'api/working-with-secrets.md' - 'Examples': 'api/examples.md' - - 'Shell': - - 'Introduction': 'shell/intro.md' - 'Miscellaneous': - 'Reports': 'miscellaneous/reports.md' + - 'Shell': 'miscellaneous/shell.md' - 'Development': - 'Utility Views': 'development/utility-views.md' From a7f0b5adb328de593c8107b31cd973dcaf208e55 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 13:38:23 -0400 Subject: [PATCH 03/25] Refreshed installation docs --- docs/installation/netbox.md | 23 ++++++++++++++--------- docs/installation/postgresql.md | 28 ++++++++++++++++------------ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/docs/installation/netbox.md b/docs/installation/netbox.md index b92fa3ad1..530456a56 100644 --- a/docs/installation/netbox.md +++ b/docs/installation/netbox.md @@ -1,18 +1,23 @@ # Installation +This section of the documentation discusses installing and configuring the NetBox application. + +!!! note + Python 3 is strongly encouraged for new installations. Support for Python 2 will be discontinued in the near future. This documentation includes a guide on [migrating from Python 2 to Python 3](migrating-to-python3). + **Ubuntu** Python 3: ```no-highlight -# apt-get install -y python3 python3-dev python3-setuptools libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev +# apt-get install -y python3 python3-dev python3-setuptools build-essential libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev # easy_install3 pip ``` Python 2: ```no-highlight -# apt-get install -y python2.7 python-dev python-setuptools libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev +# apt-get install -y python2.7 python-dev python-setuptools build-essential libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev # easy_install pip ``` @@ -163,13 +168,13 @@ You may use the script located at `netbox/generate_secret_key.py` to generate a # Run Database Migrations !!! warning - The examples on the rest of this page call the `python` executable, which will be Python2 on most systems. Replace this with `python3` if you're running NetBox on Python3. + The examples on the rest of this page call the `python3` executable. Replace this with `python2` or `python` if you're using Python 2. -Before NetBox can run, we need to install the database schema. This is done by running `python manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example): +Before NetBox can run, we need to install the database schema. This is done by running `python3 manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example): ```no-highlight # cd /opt/netbox/netbox/ -# python manage.py migrate +# python3 manage.py migrate Operations to perform: Apply all migrations: dcim, sessions, admin, ipam, utilities, auth, circuits, contenttypes, extras, secrets, users Running migrations: @@ -187,7 +192,7 @@ If this step results in a PostgreSQL authentication error, ensure that the usern NetBox does not come with any predefined user accounts. You'll need to create a super user to be able to log into NetBox: ```no-highlight -# python manage.py createsuperuser +# python3 manage.py createsuperuser Username: admin Email address: admin@example.com Password: @@ -198,7 +203,7 @@ Superuser created successfully. # Collect Static Files ```no-highlight -# python manage.py collectstatic --no-input +# python3 manage.py collectstatic --no-input You have requested to collect static files at the destination location as specified in your settings: @@ -219,7 +224,7 @@ NetBox ships with some initial data to help you get started: RIR definitions, co This step is optional. It's perfectly fine to start using NetBox without using this initial data if you'd rather create everything from scratch. ```no-highlight -# python manage.py loaddata initial_data +# python3 manage.py loaddata initial_data Installed 43 object(s) from 4 fixture(s) ``` @@ -228,7 +233,7 @@ Installed 43 object(s) from 4 fixture(s) At this point, NetBox should be able to run. We can verify this by starting a development instance: ```no-highlight -# python manage.py runserver 0.0.0.0:8000 --insecure +# python3 manage.py runserver 0.0.0.0:8000 --insecure Performing system checks... System check identified no issues (0 silenced). diff --git a/docs/installation/postgresql.md b/docs/installation/postgresql.md index 592ba1f38..dd38fec69 100644 --- a/docs/installation/postgresql.md +++ b/docs/installation/postgresql.md @@ -1,16 +1,16 @@ -NetBox requires a PostgreSQL 9.4 or higher database to store data. (Please note that MySQL is not supported, as NetBox leverages PostgreSQL's built-in [network address types](https://www.postgresql.org/docs/current/static/datatype-net-types.html).) +NetBox requires a PostgreSQL database to store data. This can be hosted locally or on a remote server. (Please note that MySQL is not supported, as NetBox leverages PostgreSQL's built-in [network address types](https://www.postgresql.org/docs/current/static/datatype-net-types.html).) !!! note - The installation instructions provided here have been tested to work on Ubuntu 16.04 and CentOS 6.9. The particular commands needed to install dependencies on other distributions may vary significantly. Unfortunately, this is outside the control of the NetBox maintainers. Please consult your distribution's documentation for assistance with any errors. + The installation instructions provided here have been tested to work on Ubuntu 16.04 and CentOS 7.4. The particular commands needed to install dependencies on other distributions may vary significantly. Unfortunately, this is outside the control of the NetBox maintainers. Please consult your distribution's documentation for assistance with any errors. !!! warning - NetBox v2.2 or later requires PostgreSQL 9.4.0 or higher. + NetBox v2.2 and later requires PostgreSQL 9.4 or higher. # Installation **Ubuntu** -If a recent enough version of PostgreSQL is not available through your distribution's package manager, consider installing from an official [PostgreSQL repository](https://wiki.postgresql.org/wiki/Apt). +If a recent enough version of PostgreSQL is not available through your distribution's package manager, you'll need to install it from an official [PostgreSQL repository](https://wiki.postgresql.org/wiki/Apt). ```no-highlight # apt-get update @@ -19,22 +19,26 @@ If a recent enough version of PostgreSQL is not available through your distribut **CentOS** +CentOS 7.4 does not ship with a recent enough version of PostgreSQL, so it will need to be installed from an external repository. The instructions below show the installation of PostgreSQL 9.6. + ```no-highlight -# yum install -y postgresql postgresql-server postgresql-devel -# postgresql-setup initdb +# yum install https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm +# yum install postgresql96 postgresql96-server postgresql96-devel +# /usr/pgsql-9.6/bin/postgresql96-setup initdb ``` -CentOS users should modify the PostgreSQL configuration to accept password-based authentication by replacing `ident` with `md5` for all host entries within `/var/lib/pgsql/data/pg_hba.conf`. For example: +CentOS users should modify the PostgreSQL configuration to accept password-based authentication by replacing `ident` with `md5` for all host entries within `/var/lib/pgsql/9.6/data/pg_hba.conf`. For example: ```no-highlight host all all 127.0.0.1/32 md5 host all all ::1/128 md5 ``` -Then, start the service: +Then, start the service and enable it to run at boot: ```no-highlight -# systemctl start postgresql +# systemctl start postgresql-9.6 +# systemctl enable postgresql-9.6 ``` # Database Creation @@ -58,10 +62,10 @@ GRANT postgres=# \q ``` -You can verify that authentication works issuing the following command and providing the configured password: +You can verify that authentication works issuing the following command and providing the configured password. (Replace `localhost` with your database server if using a remote database.) ```no-highlight -# psql -U netbox -h localhost -W +# psql -U netbox -W -h localhost netbox ``` -If successful, you will enter a `postgres` prompt. Type `\q` to exit. +If successful, you will enter a `netbox` prompt. Type `\q` to exit. From 38d23331654d980c8e8eb53e4c57b8ec59f891ca Mon Sep 17 00:00:00 2001 From: Ryan Breaker Date: Thu, 12 Oct 2017 12:39:28 -0500 Subject: [PATCH 04/25] Add meta tags for charset and convert some tabs to spaces for consistency (#1574) * Add meta tag for charset. * Add meta tag for charset in 500.html and convert some tabs to spaces for consistency. --- netbox/templates/500.html | 5 +++-- netbox/templates/_base.html | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/netbox/templates/500.html b/netbox/templates/500.html index 575694b13..2857325b9 100644 --- a/netbox/templates/500.html +++ b/netbox/templates/500.html @@ -3,9 +3,10 @@ - Server Error - + Server Error + + diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 1a187a681..17efcadd7 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -3,12 +3,13 @@ - {% block title %}Home{% endblock %} - NetBox - + {% block title %}Home{% endblock %} - NetBox + - + + From 3a0b57b50fbf29fe853488d106fe0fe77506e709 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 13:47:44 -0400 Subject: [PATCH 05/25] Fixed typo --- netbox/extras/management/commands/runreport.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/extras/management/commands/runreport.py b/netbox/extras/management/commands/runreport.py index 9adf6b130..05083b7f7 100644 --- a/netbox/extras/management/commands/runreport.py +++ b/netbox/extras/management/commands/runreport.py @@ -12,7 +12,6 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('reports', nargs='+', help="Report(s) to run") - # parser.add_argument('--verbose', action='store_true', default=False, help="Print all logs") def handle(self, *args, **options): @@ -22,7 +21,7 @@ class Command(BaseCommand): # Run reports for module_name, report_list in reports: for report in report_list: - if module_name in options['reports'] or report.full_namel in options['reports']: + if module_name in options['reports'] or report.full_name in options['reports']: # Run the report and create a new ReportResult self.stdout.write( From bb898b719f721012e6aebc89eb9302dde16eded9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 13:48:08 -0400 Subject: [PATCH 06/25] Added reports CLI documentation --- docs/miscellaneous/reports.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/miscellaneous/reports.md b/docs/miscellaneous/reports.md index c6369283c..aae258f00 100644 --- a/docs/miscellaneous/reports.md +++ b/docs/miscellaneous/reports.md @@ -117,3 +117,13 @@ Our example report above would be called as: ``` POST /api/extras/reports/devices.DeviceConnectionsReport/run/ ``` + +### Via the CLI + +Reports can be run on the CLI by invoking the management command: + +``` +python3 manage.py runreport +``` + +One or more report modules may be specified. From 9d8daca54d18294030dd31255028c1c3ae678828 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 13:54:04 -0400 Subject: [PATCH 07/25] Release v2.2.0 --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 7272da8ae..36d079aee 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -13,7 +13,7 @@ except ImportError: ) -VERSION = '2.2.0-dev' +VERSION = '2.2.0' BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) From 7f4d96f33ef86626bf0b26e448e04b39508cf121 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 14:01:52 -0400 Subject: [PATCH 08/25] Post-release version bump --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 36d079aee..e31afcf74 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -13,7 +13,7 @@ except ImportError: ) -VERSION = '2.2.0' +VERSION = '2.2.1-dev' BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) From b04ade8060d52bdd798020cd1cfb641a6cb1b5dc Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 16:02:15 -0400 Subject: [PATCH 09/25] Fixes #1576: Move PostgreSQL validation logic into the relevant migration --- netbox/extras/migrations/0008_reports.py | 23 ++++++++++++++++++++++- netbox/netbox/__init__.py | 18 ------------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/netbox/extras/migrations/0008_reports.py b/netbox/extras/migrations/0008_reports.py index c9fc16cc3..8d91ed4bd 100644 --- a/netbox/extras/migrations/0008_reports.py +++ b/netbox/extras/migrations/0008_reports.py @@ -1,11 +1,31 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.4 on 2017-09-26 21:25 from __future__ import unicode_literals +from distutils.version import StrictVersion from django.conf import settings import django.contrib.postgres.fields.jsonb -from django.db import migrations, models +from django.db import connection, migrations, models import django.db.models.deletion +from django.db.utils import OperationalError + + +def verify_postgresql_version(apps, schema_editor): + """ + Verify that PostgreSQL is version 9.4 or higher. + """ + try: + with connection.cursor() as cursor: + cursor.execute("SELECT VERSION()") + row = cursor.fetchone() + pg_version = row[0].split()[1] + if StrictVersion(pg_version) < StrictVersion('9.4.0'): + raise Exception("PostgreSQL 9.4.0 or higher is required ({} found). Upgrade PostgreSQL and then run migrations again.".format(pg_version)) + + # Skip if the database is missing (e.g. for CI testing) or misconfigured. + except OperationalError: + pass + class Migration(migrations.Migration): @@ -16,6 +36,7 @@ class Migration(migrations.Migration): ] operations = [ + migrations.RunPython(verify_postgresql_version), migrations.CreateModel( name='ReportResult', fields=[ diff --git a/netbox/netbox/__init__.py b/netbox/netbox/__init__.py index 361659e58..e69de29bb 100644 --- a/netbox/netbox/__init__.py +++ b/netbox/netbox/__init__.py @@ -1,18 +0,0 @@ -from distutils.version import StrictVersion - -from django.db import connection -from django.db.utils import OperationalError - - -# NetBox v2.2 and later requires PostgreSQL 9.4 or higher. -try: - with connection.cursor() as cursor: - cursor.execute("SELECT VERSION()") - row = cursor.fetchone() - pg_version = row[0].split()[1] - if StrictVersion(pg_version) < StrictVersion('9.4.0'): - raise Exception("PostgreSQL 9.4.0 or higher is required. ({} found)".format(pg_version)) - -# Skip if the database is missing (e.g. for CI testing) or misconfigured. -except OperationalError: - pass From 800bdd8fc50a6c69f64541807bec6c6841d3eeaf Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 16:04:01 -0400 Subject: [PATCH 10/25] Release v2.2.1 --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e31afcf74..e0f83964e 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -13,7 +13,7 @@ except ImportError: ) -VERSION = '2.2.1-dev' +VERSION = '2.2.1' BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) From 75d840fa1a0ccec700e1f7ef0edf38c5caa6b60c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 16:07:13 -0400 Subject: [PATCH 11/25] PEP8 fix --- netbox/extras/migrations/0008_reports.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/extras/migrations/0008_reports.py b/netbox/extras/migrations/0008_reports.py index 8d91ed4bd..83565cce7 100644 --- a/netbox/extras/migrations/0008_reports.py +++ b/netbox/extras/migrations/0008_reports.py @@ -27,7 +27,6 @@ def verify_postgresql_version(apps, schema_editor): pass - class Migration(migrations.Migration): dependencies = [ From 881fdbe893b3f021bd92565f6c7056b73e592b77 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 12 Oct 2017 16:39:51 -0400 Subject: [PATCH 12/25] Post-release version bump --- netbox/netbox/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e0f83964e..1e76893b7 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -13,7 +13,7 @@ except ImportError: ) -VERSION = '2.2.1' +VERSION = '2.2.2-dev' BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) From 4cb0be4df3cb01f4708c9ccc85f7a9ace69cde82 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 10:42:45 -0400 Subject: [PATCH 13/25] Fixes #1582: Add virtual_machine attribute to IPAddress --- netbox/ipam/models.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 791ba1b1a..73a522d63 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -440,7 +440,7 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel): self.get_status_display(), self.get_role_display(), self.device.identifier if self.device else None, - self.virtual_machine.name if self.device else None, + self.virtual_machine.name if self.virtual_machine else None, self.interface.name if self.interface else None, is_primary, self.description, @@ -452,6 +452,12 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel): return self.interface.device return None + @property + def virtual_machine(self): + if self.interface: + return self.interface.virtual_machine + return None + def get_status_class(self): return STATUS_CHOICE_CLASSES[self.status] From 6c27e6c4fe34b8983519b5d85a84742f6b8555fc Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 10:45:34 -0400 Subject: [PATCH 14/25] Fixes #1584: Colorized virtual machine role column --- netbox/virtualization/tables.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/netbox/virtualization/tables.py b/netbox/virtualization/tables.py index f7b7ffbe9..a8f9068ac 100644 --- a/netbox/virtualization/tables.py +++ b/netbox/virtualization/tables.py @@ -24,6 +24,10 @@ VIRTUALMACHINE_STATUS = """ {{ record.get_status_display }} """ +VIRTUALMACHINE_ROLE = """ + +""" + VIRTUALMACHINE_PRIMARY_IP = """ {{ record.primary_ip6.address.ip|default:"" }} {% if record.primary_ip6 and record.primary_ip4 %}
{% endif %} @@ -93,6 +97,7 @@ class VirtualMachineTable(BaseTable): name = tables.LinkColumn() status = tables.TemplateColumn(template_code=VIRTUALMACHINE_STATUS) cluster = tables.LinkColumn('virtualization:cluster', args=[Accessor('cluster.pk')]) + role = tables.TemplateColumn(VIRTUALMACHINE_ROLE) tenant = tables.LinkColumn('tenancy:tenant', args=[Accessor('tenant.slug')]) class Meta(BaseTable.Meta): From 17493ff655bcbd8ec36f7e23d8a27d7bb3870908 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 10:53:25 -0400 Subject: [PATCH 15/25] Closes #1587: Add primary IP column for virtual machines in global search results --- netbox/netbox/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py index 5ec81cb25..f41ff53c2 100644 --- a/netbox/netbox/views.py +++ b/netbox/netbox/views.py @@ -27,7 +27,7 @@ from tenancy.models import Tenant from tenancy.tables import TenantTable from virtualization.filters import ClusterFilter, VirtualMachineFilter from virtualization.models import Cluster, VirtualMachine -from virtualization.tables import ClusterTable, VirtualMachineTable +from virtualization.tables import ClusterTable, VirtualMachineDetailTable from .forms import SearchForm @@ -126,9 +126,11 @@ SEARCH_TYPES = OrderedDict(( 'url': 'virtualization:cluster_list', }), ('virtualmachine', { - 'queryset': VirtualMachine.objects.select_related('cluster', 'tenant', 'platform'), + 'queryset': VirtualMachine.objects.select_related( + 'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', + ), 'filter': VirtualMachineFilter, - 'table': VirtualMachineTable, + 'table': VirtualMachineDetailTable, 'url': 'virtualization:virtualmachine_list', }), )) From 023ff6834aaab5aa895d5a7d41692cd5891f8b0c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 11:50:06 -0400 Subject: [PATCH 16/25] Designated new Docker build repo; removed stale Heroku build repo --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d946215d5..26aa0ccfc 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,5 @@ Please see [the documentation](http://netbox.readthedocs.io/en/stable/) for inst ## Alternative Installations -* [Docker container](https://github.com/digitalocean/netbox-docker) -* [Heroku deployment](https://heroku.com/deploy?template=https://github.com/BILDQUADRAT/netbox/tree/heroku) (via [@mraerino](https://github.com/BILDQUADRAT/netbox/tree/heroku)) -* [Vagrant deployment](https://github.com/ryanmerolle/netbox-vagrant) +* [Docker container](https://github.com/ninech/netbox-docker) (via [@cimnine](https://github.com/cimnine)) +* [Vagrant deployment](https://github.com/ryanmerolle/netbox-vagrant) (via [@ryanmerolle](https://github.com/ryanmerolle)) From 60b4f1f89fbbf6ded72a95861673e95e9364d02b Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 12:14:19 -0400 Subject: [PATCH 17/25] Fixes #1585: Fixed slug-based filtering of virtual machines --- netbox/virtualization/filters.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/netbox/virtualization/filters.py b/netbox/virtualization/filters.py index 870ac85c6..4ddad4d5b 100644 --- a/netbox/virtualization/filters.py +++ b/netbox/virtualization/filters.py @@ -78,7 +78,7 @@ class VirtualMachineFilter(CustomFieldFilterSet): label='Cluster group (ID)', ) cluster_group = NullableModelMultipleChoiceFilter( - name='cluster__group__slug', + name='cluster__group', queryset=ClusterGroup.objects.all(), to_field_name='slug', label='Cluster group (slug)', @@ -88,12 +88,10 @@ class VirtualMachineFilter(CustomFieldFilterSet): label='Cluster (ID)', ) role_id = NullableModelMultipleChoiceFilter( - name='role_id', queryset=DeviceRole.objects.all(), label='Role (ID)', ) role = NullableModelMultipleChoiceFilter( - name='role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label='Role (slug)', @@ -112,7 +110,6 @@ class VirtualMachineFilter(CustomFieldFilterSet): label='Platform (ID)', ) platform = NullableModelMultipleChoiceFilter( - name='platform', queryset=Platform.objects.all(), to_field_name='slug', label='Platform (slug)', From 91b6ebb0c00559bb07a5c5d1076ae851330fd319 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 14:19:41 -0400 Subject: [PATCH 18/25] Closes #1580: Allow cluster assignment when bulk importing devices --- netbox/dcim/forms.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 820477e24..f0b0f6d52 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -17,6 +17,7 @@ from utilities.forms import ( ExpandableNameField, FilterChoiceField, FlexibleModelChoiceField, Livesearch, SelectWithDisabled, SmallTextarea, SlugField, FilterTreeNodeMultipleChoiceField, ) +from virtualization.models import Cluster from .formfields import MACAddressFormField from .models import ( DeviceBay, DeviceBayTemplate, CONNECTION_STATUS_CHOICES, CONNECTION_STATUS_CONNECTED, ConsolePort, @@ -900,11 +901,20 @@ class DeviceCSVForm(BaseDeviceCSVForm): required=False, help_text='Mounted rack face' ) + cluster = forms.ModelChoiceField( + queryset=Cluster.objects.all(), + to_field_name='name', + required=False, + help_text='Virtualization cluster', + error_messages={ + 'invalid_choice': 'Invalid cluster name.', + } + ) class Meta(BaseDeviceCSVForm.Meta): fields = [ 'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status', - 'site', 'rack_group', 'rack_name', 'position', 'face', + 'site', 'rack_group', 'rack_name', 'position', 'face', 'cluster', ] def clean(self): @@ -940,11 +950,19 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm): device_bay_name = forms.CharField( help_text='Name of device bay', ) + cluster = forms.ModelChoiceField( + queryset=Cluster.objects.all(), + to_field_name='name', + help_text='Virtualization cluster', + error_messages={ + 'invalid_choice': 'Invalid cluster name.', + } + ) class Meta(BaseDeviceCSVForm.Meta): fields = [ 'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status', - 'parent', 'device_bay_name', + 'parent', 'device_bay_name', 'cluster', ] def clean(self): From 34259d5d9dcd129ad40f32c2e4a81c7d3e4acbe2 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 13 Oct 2017 14:29:55 -0400 Subject: [PATCH 19/25] Removed deprecated xstr and expand_pattern functions --- netbox/dcim/views.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 387af4b61..13710c310 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -34,32 +34,6 @@ from .models import ( ) -EXPANSION_PATTERN = '\[(\d+-\d+)\]' - - -def xstr(s): - """ - Replace None with an empty string (for CSV export) - """ - return '' if s is None else str(s) - - -def expand_pattern(string): - """ - Expand a numeric pattern into a list of strings. Examples: - 'ge-0/0/[0-3]' => ['ge-0/0/0', 'ge-0/0/1', 'ge-0/0/2', 'ge-0/0/3'] - 'xe-0/[0-3]/[0-7]' => ['xe-0/0/0', 'xe-0/0/1', 'xe-0/0/2', ... 'xe-0/3/5', 'xe-0/3/6', 'xe-0/3/7'] - """ - lead, pattern, remnant = re.split(EXPANSION_PATTERN, string, maxsplit=1) - x, y = pattern.split('-') - for i in range(int(x), int(y) + 1): - if remnant: - for string in expand_pattern(remnant): - yield "{0}{1}{2}".format(lead, i, string) - else: - yield "{0}{1}".format(lead, i) - - class BulkDisconnectView(View): """ An extendable view for disconnection console/power/interface components in bulk. From 5fc3eac0f669fccd0fae89ce84aa862bbcbe9af2 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 16 Oct 2017 10:13:39 +0000 Subject: [PATCH 20/25] Avoid creating repeated graph nodes where device matches multiple regexps Fixes #1498 --- netbox/extras/models.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/extras/models.py b/netbox/extras/models.py index 5181e88e9..1e7a73166 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -274,6 +274,7 @@ class TopologyMap(models.Model): # Construct the graph graph = graphviz.Graph() graph.graph_attr['ranksep'] = '1' + seen = set() for i, device_set in enumerate(self.device_sets): subgraph = graphviz.Graph(name='sg{}'.format(i)) @@ -288,6 +289,9 @@ class TopologyMap(models.Model): devices = [] for query in device_set.strip(';').split(';'): # Split regexes on semicolons devices += Device.objects.filter(name__regex=query).select_related('device_role') + # Remove duplicate devices + devices = [d for d in devices if d.id not in seen] + seen.update([d.id for d in devices]) for d in devices: bg_color = '#{}'.format(d.device_role.color) fg_color = '#{}'.format(foreground_color(d.device_role.color)) From 047f22e1103ad530c78701b3d9929e96a88b4b38 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 16 Oct 2017 16:44:15 -0400 Subject: [PATCH 21/25] Fixes #1605: Added clusters and virtual machines to object list for global search --- netbox/netbox/forms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/netbox/forms.py b/netbox/netbox/forms.py index 72a3ab8de..0521f2d2f 100644 --- a/netbox/netbox/forms.py +++ b/netbox/netbox/forms.py @@ -30,6 +30,10 @@ OBJ_TYPE_CHOICES = ( ('Tenancy', ( ('tenant', 'Tenants'), )), + ('Virtualization', ( + ('cluster', 'Clusters'), + ('virtualmachine', 'Virtual machines'), + )), ) From 6f2f8697aec9470c036e400c5550ec6dce3a1907 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 17 Oct 2017 09:23:53 -0400 Subject: [PATCH 22/25] Fixes #1609: Added missing virtual_machine field to IP address interface serializer --- netbox/ipam/api/serializers.py | 13 ++++++++++++- netbox/ipam/api/views.py | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index a5b64fca6..36394dad2 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -240,12 +240,22 @@ class WritablePrefixSerializer(CustomFieldModelSerializer): # IP addresses # +class IPAddressInterfaceSerializer(InterfaceSerializer): + virtual_machine = NestedVirtualMachineSerializer() + + class Meta(InterfaceSerializer.Meta): + fields = [ + 'id', 'device', 'virtual_machine', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', + 'mgmt_only', 'description', 'is_connected', 'interface_connection', 'circuit_termination', + ] + + class IPAddressSerializer(CustomFieldModelSerializer): vrf = NestedVRFSerializer() tenant = NestedTenantSerializer() status = ChoiceFieldSerializer(choices=IPADDRESS_STATUS_CHOICES) role = ChoiceFieldSerializer(choices=IPADDRESS_ROLE_CHOICES) - interface = InterfaceSerializer() + interface = IPAddressInterfaceSerializer() class Meta: model = IPAddress @@ -262,6 +272,7 @@ class NestedIPAddressSerializer(serializers.ModelSerializer): model = IPAddress fields = ['id', 'url', 'family', 'address'] + IPAddressSerializer._declared_fields['nat_inside'] = NestedIPAddressSerializer() IPAddressSerializer._declared_fields['nat_outside'] = NestedIPAddressSerializer() diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index dabb518ae..b615b470f 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -151,7 +151,7 @@ class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet): queryset = IPAddress.objects.select_related( 'vrf__tenant', 'tenant', 'nat_inside' ).prefetch_related( - 'interface__device' + 'interface__device', 'interface__virtual_machine' ) serializer_class = serializers.IPAddressSerializer write_serializer_class = serializers.WritableIPAddressSerializer From 34f1a9ebfb6faa4c98fb6792fb3994a18f860990 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 17 Oct 2017 09:59:35 -0400 Subject: [PATCH 23/25] Fixes #1579: Devices already assigned to a cluster cannot be added to a different cluster --- netbox/templates/virtualization/cluster_add_devices.html | 7 ++++++- netbox/virtualization/forms.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/netbox/templates/virtualization/cluster_add_devices.html b/netbox/templates/virtualization/cluster_add_devices.html index 2029ea5b8..0a792e0c4 100644 --- a/netbox/templates/virtualization/cluster_add_devices.html +++ b/netbox/templates/virtualization/cluster_add_devices.html @@ -59,6 +59,7 @@