From 83a8d954e023e283719c2227d7a458ffe5b08956 Mon Sep 17 00:00:00 2001 From: "BeryJu.org Deployment Account" Date: Sat, 21 Jan 2017 17:49:38 +0100 Subject: [PATCH 1/7] Rudimentary python3 support --- .gitignore | 1 + .travis.yml | 3 +++ netbox/circuits/models.py | 8 +++--- netbox/dcim/forms.py | 2 +- netbox/dcim/models.py | 44 +++++++++++++++--------------- netbox/extras/models.py | 14 +++++----- netbox/generate_secret_key.py | 2 +- netbox/ipam/models.py | 18 ++++++------- netbox/manage.py | 2 +- netbox/netbox/settings.py | 50 +++++++++++++++++------------------ netbox/netbox/urls.py | 2 +- netbox/secrets/models.py | 6 ++--- netbox/tenancy/models.py | 4 +-- netbox/tenancy/views.py | 2 +- 14 files changed, 81 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 4fc377333ef..a86cd73ae7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.pyc /netbox/netbox/configuration.py +/netbox/netbox/ldap_config.py /netbox/static .idea /*.sh diff --git a/.travis.yml b/.travis.yml index e8822e5e330..b23c9d8fc54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,9 @@ env: language: python python: - "2.7" + - "3.4" + - "3.5" + - "3.6" install: - pip install -r requirements.txt - pip install pep8 diff --git a/netbox/circuits/models.py b/netbox/circuits/models.py index 7f6cc4f2154..9972e564f9f 100644 --- a/netbox/circuits/models.py +++ b/netbox/circuits/models.py @@ -51,7 +51,7 @@ class Provider(CreatedUpdatedModel, CustomFieldModel): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -78,7 +78,7 @@ class CircuitType(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -105,7 +105,7 @@ class Meta: ordering = ['provider', 'cid'] unique_together = ['provider', 'cid'] - def __unicode__(self): + def __str__(self): return u'{} {}'.format(self.provider, self.cid) def get_absolute_url(self): @@ -156,7 +156,7 @@ class Meta: ordering = ['circuit', 'term_side'] unique_together = ['circuit', 'term_side'] - def __unicode__(self): + def __str__(self): return u'{} (Side {})'.format(self.circuit, self.get_term_side_display()) def get_peer_termination(self): diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index cb35ff88109..9931ffd8b21 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -13,7 +13,7 @@ SlugField, ) -from formfields import MACAddressFormField +from .formfields import MACAddressFormField from .models import ( DeviceBay, DeviceBayTemplate, CONNECTION_STATUS_CHOICES, CONNECTION_STATUS_PLANNED, CONNECTION_STATUS_CONNECTED, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceRole, DeviceType, diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 6274f3a53aa..b2d6543eb4a 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -222,7 +222,7 @@ class Site(CreatedUpdatedModel, CustomFieldModel): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -282,7 +282,7 @@ class Meta: ['site', 'slug'], ] - def __unicode__(self): + def __str__(self): return u'{} - {}'.format(self.site.name, self.name) def get_absolute_url(self): @@ -300,7 +300,7 @@ class RackRole(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -343,7 +343,7 @@ class Meta: ['site', 'facility_id'], ] - def __unicode__(self): + def __str__(self): return self.display_name def get_absolute_url(self): @@ -487,7 +487,7 @@ class Manufacturer(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -538,7 +538,7 @@ class Meta: ['manufacturer', 'slug'], ] - def __unicode__(self): + def __str__(self): return self.model def __init__(self, *args, **kwargs): @@ -619,7 +619,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -634,7 +634,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -649,7 +649,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -664,7 +664,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -721,7 +721,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -736,7 +736,7 @@ class Meta: ordering = ['device_type', 'name'] unique_together = ['device_type', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -756,7 +756,7 @@ class DeviceRole(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -776,7 +776,7 @@ class Platform(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -828,7 +828,7 @@ class Meta: ordering = ['name'] unique_together = ['rack', 'position', 'face'] - def __unicode__(self): + def __str__(self): return self.display_name def get_absolute_url(self): @@ -982,7 +982,7 @@ class Meta: ordering = ['device', 'name'] unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return self.name # Used for connections export @@ -1023,7 +1023,7 @@ class ConsoleServerPort(models.Model): class Meta: unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -1041,7 +1041,7 @@ class Meta: ordering = ['device', 'name'] unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return self.name # Used for connections export @@ -1076,7 +1076,7 @@ class PowerOutlet(models.Model): class Meta: unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return self.name @@ -1099,7 +1099,7 @@ class Meta: ordering = ['device', 'name'] unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return self.name def clean(self): @@ -1189,7 +1189,7 @@ class Meta: ordering = ['device', 'name'] unique_together = ['device', 'name'] - def __unicode__(self): + def __str__(self): return u'{} - {}'.format(self.device.name, self.name) def clean(self): @@ -1223,5 +1223,5 @@ class Meta: ordering = ['device__id', 'parent__id', 'name'] unique_together = ['device', 'parent', 'name'] - def __unicode__(self): + def __str__(self): return self.name diff --git a/netbox/extras/models.py b/netbox/extras/models.py index d45e4846f9b..31f959dd082 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -114,7 +114,7 @@ class CustomField(models.Model): class Meta: ordering = ['weight', 'name'] - def __unicode__(self): + def __str__(self): return self.label or self.name.replace('_', ' ').capitalize() def serialize_value(self, value): @@ -164,7 +164,7 @@ class Meta: ordering = ['obj_type', 'obj_id'] unique_together = ['field', 'obj_type', 'obj_id'] - def __unicode__(self): + def __str__(self): return u'{} {}'.format(self.obj, self.field) @property @@ -193,7 +193,7 @@ class Meta: ordering = ['field', 'weight', 'value'] unique_together = ['field', 'value'] - def __unicode__(self): + def __str__(self): return self.value def clean(self): @@ -217,7 +217,7 @@ class Graph(models.Model): class Meta: ordering = ['type', 'weight', 'name'] - def __unicode__(self): + def __str__(self): return self.name def embed_url(self, obj): @@ -245,7 +245,7 @@ class Meta: ['content_type', 'name'] ] - def __unicode__(self): + def __str__(self): return u'{}: {}'.format(self.content_type, self.name) def to_response(self, context_dict, filename): @@ -278,7 +278,7 @@ class TopologyMap(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name @property @@ -344,7 +344,7 @@ class UserAction(models.Model): class Meta: ordering = ['-time'] - def __unicode__(self): + def __str__(self): if self.message: return u'{} {}'.format(self.user, self.message) return u'{} {} {}'.format(self.user, self.get_action_display(), self.content_type) diff --git a/netbox/generate_secret_key.py b/netbox/generate_secret_key.py index d935910f627..6855ee840d9 100755 --- a/netbox/generate_secret_key.py +++ b/netbox/generate_secret_key.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # This script will generate a random 50-character string suitable for use as a SECRET_KEY. import os import random diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index c8afc640278..c0ca2b0ad0f 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -89,7 +89,7 @@ class Meta: verbose_name = 'VRF' verbose_name_plural = 'VRFs' - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -120,7 +120,7 @@ class Meta: verbose_name = 'RIR' verbose_name_plural = 'RIRs' - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -142,7 +142,7 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel): class Meta: ordering = ['family', 'prefix'] - def __unicode__(self): + def __str__(self): return str(self.prefix) def get_absolute_url(self): @@ -216,7 +216,7 @@ class Role(models.Model): class Meta: ordering = ['weight', 'name'] - def __unicode__(self): + def __str__(self): return self.name @property @@ -292,7 +292,7 @@ class Meta: ordering = ['vrf', 'family', 'prefix'] verbose_name_plural = 'prefixes' - def __unicode__(self): + def __str__(self): return str(self.prefix) def get_absolute_url(self): @@ -409,7 +409,7 @@ class Meta: verbose_name = 'IP address' verbose_name_plural = 'IP addresses' - def __unicode__(self): + def __str__(self): return str(self.address) def get_absolute_url(self): @@ -486,7 +486,7 @@ class Meta: verbose_name = 'VLAN group' verbose_name_plural = 'VLAN groups' - def __unicode__(self): + def __str__(self): return u'{} - {}'.format(self.site.name, self.name) def get_absolute_url(self): @@ -524,7 +524,7 @@ class Meta: verbose_name = 'VLAN' verbose_name_plural = 'VLANs' - def __unicode__(self): + def __str__(self): return self.display_name def get_absolute_url(self): @@ -576,5 +576,5 @@ class Meta: ordering = ['device', 'protocol', 'port'] unique_together = ['device', 'protocol', 'port'] - def __unicode__(self): + def __str__(self): return u'{} ({}/{})'.format(self.name, self.port, self.get_protocol_display()) diff --git a/netbox/manage.py b/netbox/manage.py index 2ce3867f396..737592ae80d 100755 --- a/netbox/manage.py +++ b/netbox/manage.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os import sys diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e379372d569..dcf6874975c 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured try: - import configuration + import netbox.configuration except ImportError: raise ImproperlyConfigured("Configuration file is not present. Please define netbox/netbox/configuration.py per " "the documentation.") @@ -17,40 +17,40 @@ # Import local configuration for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']: try: - globals()[setting] = getattr(configuration, setting) + globals()[setting] = getattr(netbox.configuration, setting) except AttributeError: raise ImproperlyConfigured("Mandatory setting {} is missing from configuration.py. Please define it per the " "documentation.".format(setting)) # Default configurations -ADMINS = getattr(configuration, 'ADMINS', []) -DEBUG = getattr(configuration, 'DEBUG', False) -EMAIL = getattr(configuration, 'EMAIL', {}) -LOGIN_REQUIRED = getattr(configuration, 'LOGIN_REQUIRED', False) -BASE_PATH = getattr(configuration, 'BASE_PATH', '') +ADMINS = getattr(netbox.configuration, 'ADMINS', []) +DEBUG = getattr(netbox.configuration, 'DEBUG', False) +EMAIL = getattr(netbox.configuration, 'EMAIL', {}) +LOGIN_REQUIRED = getattr(netbox.configuration, 'LOGIN_REQUIRED', False) +BASE_PATH = getattr(netbox.configuration, 'BASE_PATH', '') if BASE_PATH: BASE_PATH = BASE_PATH.strip('/') + '/' # Enforce trailing slash only -MAINTENANCE_MODE = getattr(configuration, 'MAINTENANCE_MODE', False) -PAGINATE_COUNT = getattr(configuration, 'PAGINATE_COUNT', 50) -NETBOX_USERNAME = getattr(configuration, 'NETBOX_USERNAME', '') -NETBOX_PASSWORD = getattr(configuration, 'NETBOX_PASSWORD', '') -TIME_ZONE = getattr(configuration, 'TIME_ZONE', 'UTC') -DATE_FORMAT = getattr(configuration, 'DATE_FORMAT', 'N j, Y') -SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') -TIME_FORMAT = getattr(configuration, 'TIME_FORMAT', 'g:i a') -SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s') -DATETIME_FORMAT = getattr(configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') -SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') -BANNER_TOP = getattr(configuration, 'BANNER_TOP', False) -BANNER_BOTTOM = getattr(configuration, 'BANNER_BOTTOM', False) -PREFER_IPV4 = getattr(configuration, 'PREFER_IPV4', False) -ENFORCE_GLOBAL_UNIQUE = getattr(configuration, 'ENFORCE_GLOBAL_UNIQUE', False) +MAINTENANCE_MODE = getattr(netbox.configuration, 'MAINTENANCE_MODE', False) +PAGINATE_COUNT = getattr(netbox.configuration, 'PAGINATE_COUNT', 50) +NETBOX_USERNAME = getattr(netbox.configuration, 'NETBOX_USERNAME', '') +NETBOX_PASSWORD = getattr(netbox.configuration, 'NETBOX_PASSWORD', '') +TIME_ZONE = getattr(netbox.configuration, 'TIME_ZONE', 'UTC') +DATE_FORMAT = getattr(netbox.configuration, 'DATE_FORMAT', 'N j, Y') +SHORT_DATE_FORMAT = getattr(netbox.configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') +TIME_FORMAT = getattr(netbox.configuration, 'TIME_FORMAT', 'g:i a') +SHORT_TIME_FORMAT = getattr(netbox.configuration, 'SHORT_TIME_FORMAT', 'H:i:s') +DATETIME_FORMAT = getattr(netbox.configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') +SHORT_DATETIME_FORMAT = getattr(netbox.configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') +BANNER_TOP = getattr(netbox.configuration, 'BANNER_TOP', False) +BANNER_BOTTOM = getattr(netbox.configuration, 'BANNER_BOTTOM', False) +PREFER_IPV4 = getattr(netbox.configuration, 'PREFER_IPV4', False) +ENFORCE_GLOBAL_UNIQUE = getattr(netbox.configuration, 'ENFORCE_GLOBAL_UNIQUE', False) CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS # Attempt to import LDAP configuration if it has been defined LDAP_IGNORE_CERT_ERRORS = False try: - from ldap_config import * + from netbox.ldap_config import * LDAP_CONFIGURED = True except ImportError: LDAP_CONFIGURED = False @@ -79,9 +79,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Database -configuration.DATABASE.update({'ENGINE': 'django.db.backends.postgresql'}) +netbox.configuration.DATABASE.update({'ENGINE': 'django.db.backends.postgresql'}) DATABASES = { - 'default': configuration.DATABASE, + 'default': netbox.configuration.DATABASE, } # Email diff --git a/netbox/netbox/urls.py b/netbox/netbox/urls.py index 9d01f1773a9..bbfdee58ddb 100644 --- a/netbox/netbox/urls.py +++ b/netbox/netbox/urls.py @@ -2,7 +2,7 @@ from django.conf.urls import include, url from django.contrib import admin -from views import home, handle_500, trigger_500 +from netbox.views import home, handle_500, trigger_500 from users.views import login, logout diff --git a/netbox/secrets/models.py b/netbox/secrets/models.py index 930d6e03290..05205092735 100644 --- a/netbox/secrets/models.py +++ b/netbox/secrets/models.py @@ -76,7 +76,7 @@ def __init__(self, *args, **kwargs): self.__initial_public_key = self.public_key self.__initial_master_key_cipher = self.master_key_cipher - def __unicode__(self): + def __str__(self): return self.user.username def clean(self, *args, **kwargs): @@ -186,7 +186,7 @@ class SecretRole(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -227,7 +227,7 @@ def __init__(self, *args, **kwargs): self.plaintext = kwargs.pop('plaintext', None) super(Secret, self).__init__(*args, **kwargs) - def __unicode__(self): + def __str__(self): if self.role and self.device: return u'{} for {}'.format(self.role, self.device) return u'Secret' diff --git a/netbox/tenancy/models.py b/netbox/tenancy/models.py index 4317af196b2..c690ce7b796 100644 --- a/netbox/tenancy/models.py +++ b/netbox/tenancy/models.py @@ -17,7 +17,7 @@ class TenantGroup(models.Model): class Meta: ordering = ['name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): @@ -39,7 +39,7 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel): class Meta: ordering = ['group', 'name'] - def __unicode__(self): + def __str__(self): return self.name def get_absolute_url(self): diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index 8bc5b8c50ca..4823eababc8 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -10,7 +10,7 @@ BulkDeleteView, BulkEditView, BulkImportView, ObjectDeleteView, ObjectEditView, ObjectListView, ) -from models import Tenant, TenantGroup +from .models import Tenant, TenantGroup from . import filters, forms, tables From cc475f8b980931a89ab82718f009e6ecbd09d656 Mon Sep 17 00:00:00 2001 From: "BeryJu.org Deployment Account" Date: Sat, 21 Jan 2017 17:51:45 +0100 Subject: [PATCH 2/7] update docs and trigger Travis --- docs/installation/netbox.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation/netbox.md b/docs/installation/netbox.md index fa476b865d0..78bcd93d39c 100644 --- a/docs/installation/netbox.md +++ b/docs/installation/netbox.md @@ -3,14 +3,14 @@ **Debian/Ubuntu** ```no-highlight -# apt-get install -y python2.7 python-dev python-pip libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev +# apt-get install -y python3 python3-dev python3-pip libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev ``` **CentOS/RHEL** ```no-highlight # yum install -y epel-release -# yum install -y gcc python2 python-devel python-pip libxml2-devel libxslt-devel libffi-devel graphviz openssl-devel +# yum install -y gcc python3 python3-devel python3-pip libxml2-devel libxslt-devel libffi-devel graphviz openssl-devel ``` You may opt to install NetBox either from a numbered release or by cloning the master branch of its repository on GitHub. From 9d4c83b0ef8e33df26dcca7f3ab2b123ff1e30a3 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 21 Jan 2017 18:11:31 +0100 Subject: [PATCH 3/7] fix some of the tests --- netbox/dcim/models.py | 2 +- netbox/dcim/tests/test_apis.py | 70 ++++++++++++++++---------------- netbox/generate_secret_key.py | 2 +- netbox/secrets/tests/__init__.py | 1 - 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 6274f3a53aa..acf514ab0f4 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -442,7 +442,7 @@ def get_available_units(self, u_height=1, rack_face=None, exclude=list()): devices = self.devices.select_related('device_type').filter(position__gte=1).exclude(pk__in=exclude) # Initialize the rack unit skeleton - units = range(1, self.u_height + 1) + units = list(1, self.u_height + 1) # Remove units consumed by installed devices for d in devices: diff --git a/netbox/dcim/tests/test_apis.py b/netbox/dcim/tests/test_apis.py index 3cef017013c..f76a447454d 100644 --- a/netbox/dcim/tests/test_apis.py +++ b/netbox/dcim/tests/test_apis.py @@ -64,7 +64,7 @@ class SiteTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/sites/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -74,7 +74,7 @@ def test_get_list(self, endpoint='/{}api/dcim/sites/'.format(settings.BASE_PATH) ) def test_get_detail(self, endpoint='/{}api/dcim/sites/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -83,7 +83,7 @@ def test_get_detail(self, endpoint='/{}api/dcim/sites/1/'.format(settings.BASE_P ) def test_get_site_list_rack(self, endpoint='/{}api/dcim/sites/1/racks/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in json.loads(response.content): @@ -98,7 +98,7 @@ def test_get_site_list_rack(self, endpoint='/{}api/dcim/sites/1/racks/'.format(s ) def test_get_site_list_graphs(self, endpoint='/{}api/dcim/sites/1/graphs/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in json.loads(response.content): @@ -158,7 +158,7 @@ class RackTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/racks/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -172,7 +172,7 @@ def test_get_list(self, endpoint='/{}api/dcim/racks/'.format(settings.BASE_PATH) ) def test_get_detail(self, endpoint='/{}api/dcim/racks/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -201,7 +201,7 @@ class ManufacturersTest(APITestCase): nested_fields = standard_fields def test_get_list(self, endpoint='/{}api/dcim/manufacturers/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -211,7 +211,7 @@ def test_get_list(self, endpoint='/{}api/dcim/manufacturers/'.format(settings.BA ) def test_get_detail(self, endpoint='/{}api/dcim/manufacturers/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -249,7 +249,7 @@ class DeviceTypeTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/device-types/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -260,7 +260,7 @@ def test_get_list(self, endpoint='/{}api/dcim/device-types/'.format(settings.BAS def test_detail_list(self, endpoint='/{}api/dcim/device-types/1/'.format(settings.BASE_PATH)): # TODO: details returns list view. - # response = self.client.get(endpoint) + # response = self.client.get(endpoint).decode("utf-8") # content = json.loads(response.content) # self.assertEqual(response.status_code, status.HTTP_200_OK) # self.assertEqual( @@ -283,7 +283,7 @@ class DeviceRolesTest(APITestCase): nested_fields = ['id', 'name', 'slug'] def test_get_list(self, endpoint='/{}api/dcim/device-roles/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -293,7 +293,7 @@ def test_get_list(self, endpoint='/{}api/dcim/device-roles/'.format(settings.BAS ) def test_get_detail(self, endpoint='/{}api/dcim/device-roles/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -311,7 +311,7 @@ class PlatformsTest(APITestCase): nested_fields = ['id', 'name', 'slug'] def test_get_list(self, endpoint='/{}api/dcim/platforms/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -321,7 +321,7 @@ def test_get_list(self, endpoint='/{}api/dcim/platforms/'.format(settings.BASE_P ) def test_get_detail(self, endpoint='/{}api/dcim/platforms/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -359,7 +359,7 @@ class DeviceTest(APITestCase): nested_fields = ['id', 'name', 'display_name'] def test_get_list(self, endpoint='/{}api/dcim/devices/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for device in content: @@ -424,7 +424,7 @@ def test_get_list_flat(self, endpoint='/{}api/dcim/devices/?format=json_flat'.fo 'tenant', ] - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) device = content[0] @@ -434,7 +434,7 @@ def test_get_list_flat(self, endpoint='/{}api/dcim/devices/?format=json_flat'.fo ) def test_get_detail(self, endpoint='/{}api/dcim/devices/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -452,7 +452,7 @@ class ConsoleServerPortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/9/console-server-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for console_port in content: @@ -474,7 +474,7 @@ class ConsolePortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/1/console-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for console_port in content: @@ -492,7 +492,7 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/console-ports/'.format(s ) def test_get_detail(self, endpoint='/{}api/dcim/console-ports/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -513,7 +513,7 @@ class PowerPortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/1/power-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -527,7 +527,7 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/power-ports/'.format(set ) def test_get_detail(self, endpoint='/{}api/dcim/power-ports/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -548,7 +548,7 @@ class PowerOutletsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/11/power-outlets/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -598,7 +598,7 @@ class InterfaceTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/devices/1/interfaces/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: @@ -612,7 +612,7 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/interfaces/'.format(sett ) def test_get_detail(self, endpoint='/{}api/dcim/interfaces/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -625,18 +625,18 @@ def test_get_detail(self, endpoint='/{}api/dcim/interfaces/1/'.format(settings.B ) def test_get_graph_list(self, endpoint='/{}api/dcim/interfaces/1/graphs/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint) - content = json.loads(response.content) - self.assertEqual(response.status_code, status.HTTP_200_OK) - for i in content: - self.assertEqual( - sorted(i.keys()), - sorted(SiteTest.graph_fields), - ) + response = self.client.get(endpoint).decode("utf-8") + content = json.loads(response.content) + self.assertEqual(response.status_code, status.HTTP_200_OK) + for i in content: + self.assertEqual( + sorted(i.keys()), + sorted(SiteTest.graph_fields), + ) def test_get_interface_connections(self, endpoint='/{}api/dcim/interface-connections/4/' .format(settings.BASE_PATH)): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( @@ -658,7 +658,7 @@ class RelatedConnectionsTest(APITestCase): def test_get_list(self, endpoint=('/{}api/dcim/related-connections/?peer-device=test1-edge1&peer-interface=xe-0/0/3' .format(settings.BASE_PATH))): - response = self.client.get(endpoint) + response = self.client.get(endpoint).decode("utf-8") content = json.loads(response.content) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( diff --git a/netbox/generate_secret_key.py b/netbox/generate_secret_key.py index d935910f627..fc9a364bd44 100755 --- a/netbox/generate_secret_key.py +++ b/netbox/generate_secret_key.py @@ -5,4 +5,4 @@ charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(-_=+)' random.seed = (os.urandom(2048)) -print ''.join(random.choice(charset) for c in range(50)) +print(''.join(random.choice(charset) for c in range(50))) diff --git a/netbox/secrets/tests/__init__.py b/netbox/secrets/tests/__init__.py index b04a142280f..e69de29bb2d 100644 --- a/netbox/secrets/tests/__init__.py +++ b/netbox/secrets/tests/__init__.py @@ -1 +0,0 @@ -from test_models import * From 3fd04dca1b46124d00d2727505bba009ad33abf7 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 21 Jan 2017 18:30:19 +0100 Subject: [PATCH 4/7] fix all python3 errors --- netbox/dcim/models.py | 2 +- netbox/dcim/tests/test_apis.py | 116 ++++++++++++------------- netbox/extras/api/renderers.py | 2 +- netbox/netbox/configuration.example.py | 5 +- 4 files changed, 61 insertions(+), 64 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 6b23984f0a9..dde959e2332 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -442,7 +442,7 @@ def get_available_units(self, u_height=1, rack_face=None, exclude=list()): devices = self.devices.select_related('device_type').filter(position__gte=1).exclude(pk__in=exclude) # Initialize the rack unit skeleton - units = list(1, self.u_height + 1) + units = list(range(1, self.u_height + 1)) # Remove units consumed by installed devices for d in devices: diff --git a/netbox/dcim/tests/test_apis.py b/netbox/dcim/tests/test_apis.py index f76a447454d..0739b86ce36 100644 --- a/netbox/dcim/tests/test_apis.py +++ b/netbox/dcim/tests/test_apis.py @@ -64,8 +64,8 @@ class SiteTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/sites/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -74,8 +74,8 @@ def test_get_list(self, endpoint='/{}api/dcim/sites/'.format(settings.BASE_PATH) ) def test_get_detail(self, endpoint='/{}api/dcim/sites/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -83,10 +83,10 @@ def test_get_detail(self, endpoint='/{}api/dcim/sites/1/'.format(settings.BASE_P ) def test_get_site_list_rack(self, endpoint='/{}api/dcim/sites/1/racks/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) - for i in json.loads(response.content): + for i in json.loads(response.content.decode('utf-8')): self.assertEqual( sorted(i.keys()), sorted(self.rack_fields), @@ -98,10 +98,10 @@ def test_get_site_list_rack(self, endpoint='/{}api/dcim/sites/1/racks/'.format(s ) def test_get_site_list_graphs(self, endpoint='/{}api/dcim/sites/1/graphs/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) - for i in json.loads(response.content): + for i in json.loads(response.content.decode('utf-8')): self.assertEqual( sorted(i.keys()), sorted(self.graph_fields), @@ -158,8 +158,8 @@ class RackTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/racks/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -172,8 +172,8 @@ def test_get_list(self, endpoint='/{}api/dcim/racks/'.format(settings.BASE_PATH) ) def test_get_detail(self, endpoint='/{}api/dcim/racks/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -201,8 +201,8 @@ class ManufacturersTest(APITestCase): nested_fields = standard_fields def test_get_list(self, endpoint='/{}api/dcim/manufacturers/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -211,8 +211,8 @@ def test_get_list(self, endpoint='/{}api/dcim/manufacturers/'.format(settings.BA ) def test_get_detail(self, endpoint='/{}api/dcim/manufacturers/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -249,8 +249,8 @@ class DeviceTypeTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/device-types/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -260,8 +260,8 @@ def test_get_list(self, endpoint='/{}api/dcim/device-types/'.format(settings.BAS def test_detail_list(self, endpoint='/{}api/dcim/device-types/1/'.format(settings.BASE_PATH)): # TODO: details returns list view. - # response = self.client.get(endpoint).decode("utf-8") - # content = json.loads(response.content) + # response = self.client.get(endpoint) + # content = json.loads(response.content.decode('utf-8')) # self.assertEqual(response.status_code, status.HTTP_200_OK) # self.assertEqual( # sorted(content.keys()), @@ -283,8 +283,8 @@ class DeviceRolesTest(APITestCase): nested_fields = ['id', 'name', 'slug'] def test_get_list(self, endpoint='/{}api/dcim/device-roles/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -293,8 +293,8 @@ def test_get_list(self, endpoint='/{}api/dcim/device-roles/'.format(settings.BAS ) def test_get_detail(self, endpoint='/{}api/dcim/device-roles/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -311,8 +311,8 @@ class PlatformsTest(APITestCase): nested_fields = ['id', 'name', 'slug'] def test_get_list(self, endpoint='/{}api/dcim/platforms/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -321,8 +321,8 @@ def test_get_list(self, endpoint='/{}api/dcim/platforms/'.format(settings.BASE_P ) def test_get_detail(self, endpoint='/{}api/dcim/platforms/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -359,8 +359,8 @@ class DeviceTest(APITestCase): nested_fields = ['id', 'name', 'display_name'] def test_get_list(self, endpoint='/{}api/dcim/devices/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for device in content: self.assertEqual( @@ -424,8 +424,8 @@ def test_get_list_flat(self, endpoint='/{}api/dcim/devices/?format=json_flat'.fo 'tenant', ] - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) device = content[0] self.assertEqual( @@ -434,8 +434,8 @@ def test_get_list_flat(self, endpoint='/{}api/dcim/devices/?format=json_flat'.fo ) def test_get_detail(self, endpoint='/{}api/dcim/devices/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -452,8 +452,8 @@ class ConsoleServerPortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/9/console-server-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for console_port in content: self.assertEqual( @@ -474,8 +474,8 @@ class ConsolePortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/1/console-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for console_port in content: self.assertEqual( @@ -492,8 +492,8 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/console-ports/'.format(s ) def test_get_detail(self, endpoint='/{}api/dcim/console-ports/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -513,8 +513,8 @@ class PowerPortsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/1/power-ports/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -527,8 +527,8 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/power-ports/'.format(set ) def test_get_detail(self, endpoint='/{}api/dcim/power-ports/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -548,8 +548,8 @@ class PowerOutletsTest(APITestCase): nested_fields = ['id', 'device', 'name'] def test_get_list(self, endpoint='/{}api/dcim/devices/11/power-outlets/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -598,8 +598,8 @@ class InterfaceTest(APITestCase): ] def test_get_list(self, endpoint='/{}api/dcim/devices/1/interfaces/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -612,8 +612,8 @@ def test_get_list(self, endpoint='/{}api/dcim/devices/1/interfaces/'.format(sett ) def test_get_detail(self, endpoint='/{}api/dcim/interfaces/1/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -625,8 +625,8 @@ def test_get_detail(self, endpoint='/{}api/dcim/interfaces/1/'.format(settings.B ) def test_get_graph_list(self, endpoint='/{}api/dcim/interfaces/1/graphs/'.format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) for i in content: self.assertEqual( @@ -636,8 +636,8 @@ def test_get_graph_list(self, endpoint='/{}api/dcim/interfaces/1/graphs/'.format def test_get_interface_connections(self, endpoint='/{}api/dcim/interface-connections/4/' .format(settings.BASE_PATH)): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), @@ -658,8 +658,8 @@ class RelatedConnectionsTest(APITestCase): def test_get_list(self, endpoint=('/{}api/dcim/related-connections/?peer-device=test1-edge1&peer-interface=xe-0/0/3' .format(settings.BASE_PATH))): - response = self.client.get(endpoint).decode("utf-8") - content = json.loads(response.content) + response = self.client.get(endpoint) + content = json.loads(response.content.decode('utf-8')) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(content.keys()), diff --git a/netbox/extras/api/renderers.py b/netbox/extras/api/renderers.py index 1b1f4ac270f..0fd35c76259 100644 --- a/netbox/extras/api/renderers.py +++ b/netbox/extras/api/renderers.py @@ -50,7 +50,7 @@ class FlatJSONRenderer(renderers.BaseRenderer): def render(self, data, media_type=None, renderer_context=None): def flatten(entry): - for key, val in entry.iteritems(): + for key, val in entry.items(): if isinstance(val, dict): for child_key, child_val in flatten(val): yield "{}_{}".format(key, child_key), child_val diff --git a/netbox/netbox/configuration.example.py b/netbox/netbox/configuration.example.py index b85fcafbbc5..75d6b9e284a 100644 --- a/netbox/netbox/configuration.example.py +++ b/netbox/netbox/configuration.example.py @@ -13,10 +13,7 @@ # PostgreSQL database configuration. DATABASE = { 'NAME': 'netbox', # Database name - 'USER': '', # PostgreSQL username - 'PASSWORD': '', # PostgreSQL password - 'HOST': 'localhost', # Database server - 'PORT': '', # Database port (leave blank for default) + 'USER': 'postgres', # PostgreSQL username } # This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. From 2673faac9a6fa04c977b7d4fd2d406d7913bcd79 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 21 Jan 2017 18:36:55 +0100 Subject: [PATCH 5/7] change env calls to just python --- netbox/generate_secret_key.py | 2 +- netbox/manage.py | 2 +- netbox/netbox/configuration.example.py | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/netbox/generate_secret_key.py b/netbox/generate_secret_key.py index cc823939d8d..0e0214dc47d 100755 --- a/netbox/generate_secret_key.py +++ b/netbox/generate_secret_key.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python # This script will generate a random 50-character string suitable for use as a SECRET_KEY. import os import random diff --git a/netbox/manage.py b/netbox/manage.py index 737592ae80d..2ce3867f396 100755 --- a/netbox/manage.py +++ b/netbox/manage.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python import os import sys diff --git a/netbox/netbox/configuration.example.py b/netbox/netbox/configuration.example.py index 75d6b9e284a..b85fcafbbc5 100644 --- a/netbox/netbox/configuration.example.py +++ b/netbox/netbox/configuration.example.py @@ -13,7 +13,10 @@ # PostgreSQL database configuration. DATABASE = { 'NAME': 'netbox', # Database name - 'USER': 'postgres', # PostgreSQL username + 'USER': '', # PostgreSQL username + 'PASSWORD': '', # PostgreSQL password + 'HOST': 'localhost', # Database server + 'PORT': '', # Database port (leave blank for default) } # This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. From a61201217826ae7e94a96e9bf07e5ef21d672059 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 23 Jan 2017 18:23:55 +0100 Subject: [PATCH 6/7] add @python_2_unicode_compatible decorator to models for python2 compatibility --- netbox/circuits/models.py | 5 +++++ netbox/dcim/models.py | 23 +++++++++++++++++++++++ netbox/extras/models.py | 8 ++++++++ netbox/ipam/models.py | 10 ++++++++++ netbox/secrets/models.py | 5 ++++- netbox/tenancy/models.py | 3 +++ 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/netbox/circuits/models.py b/netbox/circuits/models.py index 9972e564f9f..6a0380dd5c1 100644 --- a/netbox/circuits/models.py +++ b/netbox/circuits/models.py @@ -1,6 +1,7 @@ from django.contrib.contenttypes.fields import GenericRelation from django.core.urlresolvers import reverse from django.db import models +from django.utils.encoding import python_2_unicode_compatible from dcim.fields import ASNField from extras.models import CustomFieldModel, CustomFieldValue @@ -33,6 +34,7 @@ def humanize_speed(speed): return '{} Kbps'.format(speed) +@python_2_unicode_compatible class Provider(CreatedUpdatedModel, CustomFieldModel): """ Each Circuit belongs to a Provider. This is usually a telecommunications company or similar organization. This model @@ -67,6 +69,7 @@ def to_csv(self): ]) +@python_2_unicode_compatible class CircuitType(models.Model): """ Circuits can be organized by their functional role. For example, a user might wish to define CircuitTypes named @@ -85,6 +88,7 @@ def get_absolute_url(self): return "{}?type={}".format(reverse('circuits:circuit_list'), self.slug) +@python_2_unicode_compatible class Circuit(CreatedUpdatedModel, CustomFieldModel): """ A communications circuit connects two points. Each Circuit belongs to a Provider; Providers may have multiple @@ -141,6 +145,7 @@ def commit_rate_human(self): commit_rate_human.admin_order_field = 'commit_rate' +@python_2_unicode_compatible class CircuitTermination(models.Model): circuit = models.ForeignKey('Circuit', related_name='terminations', on_delete=models.CASCADE) term_side = models.CharField(max_length=1, choices=TERM_SIDE_CHOICES, verbose_name='Termination') diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index dde959e2332..d29ca745d8d 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -8,6 +8,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.db.models import Count, Q, ObjectDoesNotExist +from django.utils.encoding import python_2_unicode_compatible from circuits.models import Circuit from extras.models import CustomFieldModel, CustomField, CustomFieldValue @@ -199,6 +200,7 @@ def get_queryset(self): return self.natural_order_by('name') +@python_2_unicode_compatible class Site(CreatedUpdatedModel, CustomFieldModel): """ A Site represents a geographic location within a network; typically a building or campus. The optional facility @@ -265,6 +267,7 @@ def count_circuits(self): # Racks # +@python_2_unicode_compatible class RackGroup(models.Model): """ Racks can be grouped as subsets within a Site. The scope of a group will depend on how Sites are defined. For @@ -289,6 +292,7 @@ def get_absolute_url(self): return "{}?group_id={}".format(reverse('dcim:rack_list'), self.pk) +@python_2_unicode_compatible class RackRole(models.Model): """ Racks can be organized by functional role, similar to Devices. @@ -313,6 +317,7 @@ def get_queryset(self): return self.natural_order_by('site__name', 'name') +@python_2_unicode_compatible class Rack(CreatedUpdatedModel, CustomFieldModel): """ Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face. @@ -477,6 +482,7 @@ def get_utilization(self): # Device Types # +@python_2_unicode_compatible class Manufacturer(models.Model): """ A Manufacturer represents a company which produces hardware devices; for example, Juniper or Dell. @@ -494,6 +500,7 @@ def get_absolute_url(self): return "{}?manufacturer={}".format(reverse('dcim:devicetype_list'), self.slug) +@python_2_unicode_compatible class DeviceType(models.Model, CustomFieldModel): """ A DeviceType represents a particular make (Manufacturer) and model of device. It specifies rack height and depth, as @@ -608,6 +615,7 @@ def is_child_device(self): return bool(self.subdevice_role is False) +@python_2_unicode_compatible class ConsolePortTemplate(models.Model): """ A template for a ConsolePort to be created for a new Device. @@ -623,6 +631,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class ConsoleServerPortTemplate(models.Model): """ A template for a ConsoleServerPort to be created for a new Device. @@ -638,6 +647,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class PowerPortTemplate(models.Model): """ A template for a PowerPort to be created for a new Device. @@ -653,6 +663,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class PowerOutletTemplate(models.Model): """ A template for a PowerOutlet to be created for a new Device. @@ -706,6 +717,7 @@ def order_naturally(self, method=IFACE_ORDERING_POSITION): }).order_by(*ordering) +@python_2_unicode_compatible class InterfaceTemplate(models.Model): """ A template for a physical data interface on a new Device. @@ -725,6 +737,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class DeviceBayTemplate(models.Model): """ A template for a DeviceBay to be created for a new parent Device. @@ -744,6 +757,7 @@ def __str__(self): # Devices # +@python_2_unicode_compatible class DeviceRole(models.Model): """ Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a @@ -763,6 +777,7 @@ def get_absolute_url(self): return "{}?role={}".format(reverse('dcim:device_list'), self.slug) +@python_2_unicode_compatible class Platform(models.Model): """ Platform refers to the software or firmware running on a Device; for example, "Cisco IOS-XR" or "Juniper Junos". @@ -789,6 +804,7 @@ def get_queryset(self): return self.natural_order_by('name') +@python_2_unicode_compatible class Device(CreatedUpdatedModel, CustomFieldModel): """ A Device represents a piece of physical hardware mounted within a Rack. Each Device is assigned a DeviceType, @@ -968,6 +984,7 @@ def get_rpc_client(self): return RPC_CLIENTS.get(self.platform.rpc_client) +@python_2_unicode_compatible class ConsolePort(models.Model): """ A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts. @@ -1011,6 +1028,7 @@ def get_queryset(self): }).order_by('device', 'name_as_integer') +@python_2_unicode_compatible class ConsoleServerPort(models.Model): """ A physical port within a Device (typically a designated console server) which provides access to ConsolePorts. @@ -1027,6 +1045,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class PowerPort(models.Model): """ A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets. @@ -1064,6 +1083,7 @@ def get_queryset(self): }).order_by('device', 'name_padded') +@python_2_unicode_compatible class PowerOutlet(models.Model): """ A physical power outlet (output) within a Device which provides power to a PowerPort. @@ -1080,6 +1100,7 @@ def __str__(self): return self.name +@python_2_unicode_compatible class Interface(models.Model): """ A physical data interface within a Device. An Interface can connect to exactly one other Interface via the creation @@ -1176,6 +1197,7 @@ def to_csv(self): ]) +@python_2_unicode_compatible class DeviceBay(models.Model): """ An empty space within a Device which can house a child device @@ -1205,6 +1227,7 @@ def clean(self): raise ValidationError("Cannot install a device into itself.") +@python_2_unicode_compatible class Module(models.Model): """ A Module represents a piece of hardware within a Device, such as a line card or power supply. Modules are used only diff --git a/netbox/extras/models.py b/netbox/extras/models.py index 31f959dd082..f06d0aa29a1 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -8,6 +8,7 @@ from django.db import models from django.http import HttpResponse from django.template import Template, Context +from django.utils.encoding import python_2_unicode_compatible from django.utils.safestring import mark_safe @@ -93,6 +94,7 @@ def get_custom_fields(self): return OrderedDict([(field, None) for field in fields]) +@python_2_unicode_compatible class CustomField(models.Model): obj_type = models.ManyToManyField(ContentType, related_name='custom_fields', verbose_name='Object(s)', limit_choices_to={'model__in': CUSTOMFIELD_MODELS}, @@ -153,6 +155,7 @@ def deserialize_value(self, serialized_value): return serialized_value +@python_2_unicode_compatible class CustomFieldValue(models.Model): field = models.ForeignKey('CustomField', related_name='values') obj_type = models.ForeignKey(ContentType, related_name='+', on_delete=models.PROTECT) @@ -183,6 +186,7 @@ def save(self, *args, **kwargs): super(CustomFieldValue, self).save(*args, **kwargs) +@python_2_unicode_compatible class CustomFieldChoice(models.Model): field = models.ForeignKey('CustomField', related_name='choices', limit_choices_to={'type': CF_TYPE_SELECT}, on_delete=models.CASCADE) @@ -207,6 +211,7 @@ def delete(self, using=None, keep_parents=False): CustomFieldValue.objects.filter(field__type=CF_TYPE_SELECT, serialized_value=str(pk)).delete() +@python_2_unicode_compatible class Graph(models.Model): type = models.PositiveSmallIntegerField(choices=GRAPH_TYPE_CHOICES) weight = models.PositiveSmallIntegerField(default=1000) @@ -231,6 +236,7 @@ def embed_link(self, obj): return template.render(Context({'obj': obj})) +@python_2_unicode_compatible class ExportTemplate(models.Model): content_type = models.ForeignKey(ContentType, limit_choices_to={'model__in': EXPORTTEMPLATE_MODELS}) name = models.CharField(max_length=100) @@ -264,6 +270,7 @@ def to_response(self, context_dict, filename): return response +@python_2_unicode_compatible class TopologyMap(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(unique=True) @@ -328,6 +335,7 @@ def log_bulk_delete(self, user, content_type, message=''): self.log_bulk_action(user, content_type, ACTION_BULK_DELETE, message) +@python_2_unicode_compatible class UserAction(models.Model): """ A record of an action (add, edit, or delete) performed on an object by a User. diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index c0ca2b0ad0f..d2bb3ce03f2 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -7,6 +7,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.db.models.expressions import RawSQL +from django.utils.encoding import python_2_unicode_compatible from dcim.models import Interface from extras.models import CustomFieldModel, CustomFieldValue @@ -70,6 +71,7 @@ ) +@python_2_unicode_compatible class VRF(CreatedUpdatedModel, CustomFieldModel): """ A virtual routing and forwarding (VRF) table represents a discrete layer three forwarding domain (e.g. a routing @@ -105,6 +107,7 @@ def to_csv(self): ]) +@python_2_unicode_compatible class RIR(models.Model): """ A Regional Internet Registry (RIR) is responsible for the allocation of a large portion of the global IP address @@ -127,6 +130,7 @@ def get_absolute_url(self): return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug) +@python_2_unicode_compatible class Aggregate(CreatedUpdatedModel, CustomFieldModel): """ An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize @@ -204,6 +208,7 @@ def get_utilization(self): return int(children_size / self.prefix.size * 100) +@python_2_unicode_compatible class Role(models.Model): """ A Role represents the functional role of a Prefix or VLAN; for example, "Customer," "Infrastructure," or @@ -263,6 +268,7 @@ def annotate_depth(self, limit=None): return filter(lambda p: p.depth <= limit, queryset) +@python_2_unicode_compatible class Prefix(CreatedUpdatedModel, CustomFieldModel): """ A Prefix represents an IPv4 or IPv6 network, including mask length. Prefixes can optionally be assigned to Sites and @@ -377,6 +383,7 @@ def get_queryset(self): return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('family', 'host') +@python_2_unicode_compatible class IPAddress(CreatedUpdatedModel, CustomFieldModel): """ An IPAddress represents an individual IPv4 or IPv6 address and its mask. The mask length should match what is @@ -469,6 +476,7 @@ def get_status_class(self): return STATUS_CHOICE_CLASSES[self.status] +@python_2_unicode_compatible class VLANGroup(models.Model): """ A VLAN group is an arbitrary collection of VLANs within which VLAN IDs and names must be unique. @@ -493,6 +501,7 @@ def get_absolute_url(self): return "{}?group_id={}".format(reverse('ipam:vlan_list'), self.pk) +@python_2_unicode_compatible class VLAN(CreatedUpdatedModel, CustomFieldModel): """ A VLAN is a distinct layer two forwarding domain identified by a 12-bit integer (1-4094). Each VLAN must be assigned @@ -558,6 +567,7 @@ def get_status_class(self): return STATUS_CHOICE_CLASSES[self.status] +@python_2_unicode_compatible class Service(CreatedUpdatedModel): """ A Service represents a layer-four service (e.g. HTTP or SSH) running on a Device. A Service may optionally be tied diff --git a/netbox/secrets/models.py b/netbox/secrets/models.py index 05205092735..a0c3e6f8b31 100644 --- a/netbox/secrets/models.py +++ b/netbox/secrets/models.py @@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError from django.core.urlresolvers import reverse from django.db import models -from django.utils.encoding import force_bytes +from django.utils.encoding import force_bytes, python_2_unicode_compatible from dcim.models import Device from utilities.models import CreatedUpdatedModel @@ -51,6 +51,7 @@ def delete(self): raise Exception("Bulk deletion has been disabled.") +@python_2_unicode_compatible class UserKey(CreatedUpdatedModel): """ A UserKey stores a user's personal RSA (public) encryption key, which is used to generate their unique encrypted @@ -170,6 +171,7 @@ def activate(self, master_key): self.save() +@python_2_unicode_compatible class SecretRole(models.Model): """ A SecretRole represents an arbitrary functional classification of Secrets. For example, a user might define roles @@ -201,6 +203,7 @@ def has_member(self, user): return user in self.users.all() or user.groups.filter(pk__in=self.groups.all()).exists() +@python_2_unicode_compatible class Secret(CreatedUpdatedModel): """ A Secret stores an AES256-encrypted copy of sensitive data, such as passwords or secret keys. An irreversible diff --git a/netbox/tenancy/models.py b/netbox/tenancy/models.py index c690ce7b796..df871fc3129 100644 --- a/netbox/tenancy/models.py +++ b/netbox/tenancy/models.py @@ -1,12 +1,14 @@ from django.contrib.contenttypes.fields import GenericRelation from django.core.urlresolvers import reverse from django.db import models +from django.utils.encoding import python_2_unicode_compatible from extras.models import CustomFieldModel, CustomFieldValue from utilities.models import CreatedUpdatedModel from utilities.utils import csv_format +@python_2_unicode_compatible class TenantGroup(models.Model): """ An arbitrary collection of Tenants. @@ -24,6 +26,7 @@ def get_absolute_url(self): return "{}?group={}".format(reverse('tenancy:tenant_list'), self.slug) +@python_2_unicode_compatible class Tenant(CreatedUpdatedModel, CustomFieldModel): """ A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal From d7f8ae1e88f03e4ea6478458688e8934003428b9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 23 Jan 2017 18:27:42 +0100 Subject: [PATCH 7/7] switch netbox.configuration to from netbox import configuration --- netbox/netbox/settings.py | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index dcf6874975c..c2c893e58df 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured try: - import netbox.configuration + from netbox import configuration except ImportError: raise ImproperlyConfigured("Configuration file is not present. Please define netbox/netbox/configuration.py per " "the documentation.") @@ -17,34 +17,34 @@ # Import local configuration for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']: try: - globals()[setting] = getattr(netbox.configuration, setting) + globals()[setting] = getattr(configuration, setting) except AttributeError: raise ImproperlyConfigured("Mandatory setting {} is missing from configuration.py. Please define it per the " "documentation.".format(setting)) # Default configurations -ADMINS = getattr(netbox.configuration, 'ADMINS', []) -DEBUG = getattr(netbox.configuration, 'DEBUG', False) -EMAIL = getattr(netbox.configuration, 'EMAIL', {}) -LOGIN_REQUIRED = getattr(netbox.configuration, 'LOGIN_REQUIRED', False) -BASE_PATH = getattr(netbox.configuration, 'BASE_PATH', '') +ADMINS = getattr(configuration, 'ADMINS', []) +DEBUG = getattr(configuration, 'DEBUG', False) +EMAIL = getattr(configuration, 'EMAIL', {}) +LOGIN_REQUIRED = getattr(configuration, 'LOGIN_REQUIRED', False) +BASE_PATH = getattr(configuration, 'BASE_PATH', '') if BASE_PATH: BASE_PATH = BASE_PATH.strip('/') + '/' # Enforce trailing slash only -MAINTENANCE_MODE = getattr(netbox.configuration, 'MAINTENANCE_MODE', False) -PAGINATE_COUNT = getattr(netbox.configuration, 'PAGINATE_COUNT', 50) -NETBOX_USERNAME = getattr(netbox.configuration, 'NETBOX_USERNAME', '') -NETBOX_PASSWORD = getattr(netbox.configuration, 'NETBOX_PASSWORD', '') -TIME_ZONE = getattr(netbox.configuration, 'TIME_ZONE', 'UTC') -DATE_FORMAT = getattr(netbox.configuration, 'DATE_FORMAT', 'N j, Y') -SHORT_DATE_FORMAT = getattr(netbox.configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') -TIME_FORMAT = getattr(netbox.configuration, 'TIME_FORMAT', 'g:i a') -SHORT_TIME_FORMAT = getattr(netbox.configuration, 'SHORT_TIME_FORMAT', 'H:i:s') -DATETIME_FORMAT = getattr(netbox.configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') -SHORT_DATETIME_FORMAT = getattr(netbox.configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') -BANNER_TOP = getattr(netbox.configuration, 'BANNER_TOP', False) -BANNER_BOTTOM = getattr(netbox.configuration, 'BANNER_BOTTOM', False) -PREFER_IPV4 = getattr(netbox.configuration, 'PREFER_IPV4', False) -ENFORCE_GLOBAL_UNIQUE = getattr(netbox.configuration, 'ENFORCE_GLOBAL_UNIQUE', False) +MAINTENANCE_MODE = getattr(configuration, 'MAINTENANCE_MODE', False) +PAGINATE_COUNT = getattr(configuration, 'PAGINATE_COUNT', 50) +NETBOX_USERNAME = getattr(configuration, 'NETBOX_USERNAME', '') +NETBOX_PASSWORD = getattr(configuration, 'NETBOX_PASSWORD', '') +TIME_ZONE = getattr(configuration, 'TIME_ZONE', 'UTC') +DATE_FORMAT = getattr(configuration, 'DATE_FORMAT', 'N j, Y') +SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d') +TIME_FORMAT = getattr(configuration, 'TIME_FORMAT', 'g:i a') +SHORT_TIME_FORMAT = getattr(configuration, 'SHORT_TIME_FORMAT', 'H:i:s') +DATETIME_FORMAT = getattr(configuration, 'DATETIME_FORMAT', 'N j, Y g:i a') +SHORT_DATETIME_FORMAT = getattr(configuration, 'SHORT_DATETIME_FORMAT', 'Y-m-d H:i') +BANNER_TOP = getattr(configuration, 'BANNER_TOP', False) +BANNER_BOTTOM = getattr(configuration, 'BANNER_BOTTOM', False) +PREFER_IPV4 = getattr(configuration, 'PREFER_IPV4', False) +ENFORCE_GLOBAL_UNIQUE = getattr(configuration, 'ENFORCE_GLOBAL_UNIQUE', False) CSRF_TRUSTED_ORIGINS = ALLOWED_HOSTS # Attempt to import LDAP configuration if it has been defined @@ -79,9 +79,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Database -netbox.configuration.DATABASE.update({'ENGINE': 'django.db.backends.postgresql'}) +configuration.DATABASE.update({'ENGINE': 'django.db.backends.postgresql'}) DATABASES = { - 'default': netbox.configuration.DATABASE, + 'default': configuration.DATABASE, } # Email