diff --git a/.gitignore b/.gitignore index 4fc377333..3412e8c89 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ !upgrade.sh fabfile.py *.swp + +# Heroku +.env +venv/ diff --git a/Procfile b/Procfile new file mode 100644 index 000000000..4b1f68e19 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: cd netbox && gunicorn netbox.wsgi --log-file - +release: ./netbox/manage.py migrate diff --git a/README.md b/README.md index 66c35250b..d3b905517 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![NetBox](docs/netbox_logo.png "NetBox logo") +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) + NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. NetBox runs as a web application atop the [Django](https://www.djangoproject.com/) Python framework with a [PostgreSQL](http://www.postgresql.org/) database. For a complete list of requirements, see `requirements.txt`. The code is available [on GitHub](https://github.com/digitalocean/netbox). diff --git a/app.json b/app.json new file mode 100644 index 000000000..050b83a57 --- /dev/null +++ b/app.json @@ -0,0 +1,41 @@ +{ + "name": "Netbox", + "description": "NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool.", + "repository": "https://github.com/digitalocean/netbox", + "logo": "https://github.com/BILDQUADRAT/netbox/raw/heroku/docs/netbox_logo.png", + "keywords": ["netbox", "ipam", "dcim", "digitalocean"], + "scripts": { + "postdeploy": "./netbox/manage.py migrate && echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${ADMIN_USER}', '${ADMIN_EMAIL}', '${ADMIN_PASSWORD}')\" | ./netbox/manage.py shell" + }, + "env": { + "ALLOWED_HOSTS": { + "description": "Limit hosts allowed to be used for accessing the app", + "value": "*" + }, + "LOGIN_REQUIRED": { + "description": "If true, requires a login for every action", + "value": "true" + }, + "NETBOX_CONFIG": { + "description": "Which config to pick (always 'netbox.configuration_heroku')", + "value": "netbox.configuration_heroku" + }, + "SECRET_KEY": { + "description": "Secret key for Django cookies", + "generator": "secret" + }, + "ADMIN_USER": { + "description": "Username for the initial superuser", + "value": "" + }, + "ADMIN_EMAIL": { + "description": "Email address of the superuser", + "value": "" + }, + "ADMIN_PASSWORD": { + "description": "Initial password for the superuser", + "value": "" + } + }, + "addons": ["heroku-postgresql:hobby-dev"] +} diff --git a/netbox/netbox/configuration_heroku.py b/netbox/netbox/configuration_heroku.py new file mode 100644 index 000000000..dffb51f45 --- /dev/null +++ b/netbox/netbox/configuration_heroku.py @@ -0,0 +1,74 @@ +import os +import dj_database_url +######################### +# # +# Required settings # +# # +######################### + +# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write +# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name. +# +# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local'] +ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(' ') + +# PostgreSQL database configuration. +DATABASE = dj_database_url.config() + +# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file. +# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and +# symbols. NetBox will not run without this defined. For more information, see +# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY +SECRET_KEY = os.environ.get('SECRET_KEY', '') + +######################### +# # +# Optional settings # +# # +######################### + +# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of +# application errors (assuming correct email settings are provided). +ADMINS = [ + # ['John Doe', 'jdoe@example.com'], +] + +# Email settings +EMAIL = { + 'SERVER': os.environ.get('EMAIL_SERVER', 'localhost'), + 'PORT': os.environ.get('EMAIL_PORT', 25), + 'USERNAME': os.environ.get('EMAIL_USERNAME', ''), + 'PASSWORD': os.environ.get('EMAIL_PASSWORD', ''), + 'TIMEOUT': os.environ.get('EMAIL_TIMEOUT', 10), # seconds + 'FROM_EMAIL': os.environ.get('EMAIL_FROM', ''), +} + +# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users +# are permitted to access most data in NetBox (excluding secrets) but not make any changes. +LOGIN_REQUIRED = os.environ.get('LOGIN_REQUIRED', False) + +# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set: +# BASE_PATH = 'netbox/' +BASE_PATH = os.environ.get('BASE_PATH', '') + +# Setting this to True will display a "maintenance mode" banner at the top of every page. +MAINTENANCE_MODE = os.environ.get('MAINTENANCE_MODE', False) + +# Credentials that NetBox will use to access live devices. +NETBOX_USERNAME = os.environ.get('NETBOX_USERNAME', '') +NETBOX_PASSWORD = os.environ.get('NETBOX_PASSWORD', '') + +# Determine how many objects to display per page within a list. (Default: 50) +PAGINATE_COUNT = os.environ.get('PAGINATE_COUNT', 50) + +# Time zone (default: UTC) +TIME_ZONE = os.environ.get('TIME_ZONE', 'UTC') + +# Date/time formatting. See the following link for supported formats: +# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date +DATE_FORMAT = os.environ.get('DATE_FORMAT', 'N j, Y') +SHORT_DATE_FORMAT = os.environ.get('SHORT_DATE_FORMAT', 'Y-m-d') +TIME_FORMAT = os.environ.get('TIME_FORMAT', 'g:i a') +SHORT_TIME_FORMAT = os.environ.get('SHORT_TIME_FORMAT', 'H:i:s') +DATETIME_FORMAT = os.environ.get('DATETIME_FORMAT', 'N j, Y g:i a') +SHORT_DATETIME_FORMAT = os.environ.get('SHORT_DATETIME_FORMAT', 'Y-m-d H:i') diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e379372d5..186841d17 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -1,12 +1,14 @@ import logging import os import socket +import importlib from django.contrib.messages import constants as messages from django.core.exceptions import ImproperlyConfigured try: - import configuration + mod_name = os.getenv('NETBOX_CONFIG', 'netbox.configuration') + configuration = importlib.import_module(mod_name) except ImportError: raise ImproperlyConfigured("Configuration file is not present. Please define netbox/netbox/configuration.py per " "the documentation.") diff --git a/netbox/netbox/wsgi.py b/netbox/netbox/wsgi.py index 7fac23c61..772014473 100644 --- a/netbox/netbox/wsgi.py +++ b/netbox/netbox/wsgi.py @@ -10,7 +10,9 @@ https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ import os from django.core.wsgi import get_wsgi_application +from whitenoise.django import DjangoWhiteNoise os.environ.setdefault("DJANGO_SETTINGS_MODULE", "netbox.settings") application = get_wsgi_application() +application = DjangoWhiteNoise(application) diff --git a/requirements.txt b/requirements.txt index caa678f4c..21e616e36 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,6 @@ py-gfm>=0.1.3 pycrypto>=2.6.1 sqlparse>=0.2 xmltodict>=0.10.2 +dj-database-url==0.4.1 +gunicorn==19.6.0 +whitenoise==3.2.2