Skip to content

Commit 43aea3a

Browse files
authored
Merge pull request #349 from netbox-community/develop
Version 0.26.0
2 parents 00022e7 + a52a554 commit 43aea3a

25 files changed

+421
-177
lines changed

.github/FUNDING.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# These are supported funding model platforms
2+
3+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4+
- cimnine
5+
- tobiasge
6+
patreon: # Replace with a single Patreon username
7+
open_collective: # Replace with a single Open Collective username
8+
ko_fi: # Replace with a single Ko-fi username
9+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
10+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
11+
liberapay: # Replace with a single Liberapay username
12+
issuehunt: # Replace with a single IssueHunt username
13+
otechie: # Replace with a single Otechie username
14+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.github/workflows/push.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ jobs:
1818
- ./build-next.sh
1919
- ./build.sh develop
2020
docker_from:
21-
- '' # use the default of the DOCKERFILE
22-
- python:3.7-alpine
21+
- '' # use the default of the build script
2322
- python:3.8-alpine
24-
# - python:3.9-rc-alpine # disable until Netbox's unit tests work
23+
- python:3.9-alpine
2524
fail-fast: false
2625
runs-on: ubuntu-latest
2726
name: Builds new Netbox Docker Images

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@
33
.initializers
44
docker-compose.override.yml
55
*.pem
6+
configuration/*
7+
!configuration/configuration.py
8+
!configuration/extra.py
9+
configuration/ldap/*
10+
!configuration/ldap/ldap_config.py
11+
prometheus.yml

Dockerfile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ ARG NETBOX_PATH
6161
COPY ${NETBOX_PATH} /opt/netbox
6262

6363
COPY docker/configuration.docker.py /opt/netbox/netbox/netbox/configuration.py
64-
COPY configuration/gunicorn_config.py /etc/netbox/config/
64+
COPY docker/gunicorn_config.py /etc/netbox/
6565
COPY docker/nginx.conf /etc/netbox-nginx/nginx.conf
6666
COPY docker/docker-entrypoint.sh /opt/netbox/docker-entrypoint.sh
6767
COPY startup_scripts/ /opt/netbox/startup_scripts/
6868
COPY initializers/ /opt/netbox/initializers/
69-
COPY configuration/configuration.py /etc/netbox/config/configuration.py
69+
COPY configuration/ /etc/netbox/config/
7070

7171
WORKDIR /opt/netbox/netbox
7272

@@ -79,7 +79,7 @@ RUN mkdir static && chmod -R g+w static media
7979

8080
ENTRYPOINT [ "/opt/netbox/docker-entrypoint.sh" ]
8181

82-
CMD ["gunicorn", "-c /etc/netbox/config/gunicorn_config.py", "netbox.wsgi"]
82+
CMD ["gunicorn", "-c /etc/netbox/gunicorn_config.py", "netbox.wsgi"]
8383

8484
LABEL ORIGINAL_TAG="" \
8585
NETBOX_GIT_BRANCH="" \
@@ -122,4 +122,3 @@ RUN apk add --no-cache \
122122
util-linux
123123

124124
COPY docker/ldap_config.docker.py /opt/netbox/netbox/netbox/ldap_config.py
125-
COPY configuration/ldap_config.py /etc/netbox/config/ldap_config.py

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ The default credentials are:
7979
## Documentation
8080

8181
Please refer [to our wiki on Github][netbox-docker-wiki] for further information on how to use this Netbox Docker image properly.
82-
It covers advanced topics such as using secret files, deployment to Kubernetes as well as NAPALM and LDAP configuration.
82+
It covers advanced topics such as using files for secrets, deployment to Kubernetes, monitoring and configuring NAPALM or LDAP.
8383

8484
[netbox-docker-wiki]: https://github.com/netbox-community/netbox-docker/wiki/
8585

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.25.0
1+
0.26.0

build.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ if [ "${1}x" == "x" ] || [ "${1}" == "--help" ] || [ "${1}" == "-h" ]; then
4949
echo " DOCKERFILE The name of Dockerfile to use."
5050
echo " Default: Dockerfile"
5151
echo " DOCKER_FROM The base image to use."
52-
echo " Default: 'python:3.7-alpine'"
52+
echo " Default: 'python:3.8-alpine'"
5353
echo " DOCKER_TARGET A specific target to build."
5454
echo " It's currently not possible to pass multiple targets."
5555
echo " Default: main ldap"
@@ -157,7 +157,7 @@ fi
157157
# Determining the value for DOCKER_FROM
158158
###
159159
if [ -z "$DOCKER_FROM" ]; then
160-
DOCKER_FROM="python:3.7-alpine"
160+
DOCKER_FROM="python:3.8-alpine"
161161
fi
162162

163163
###
@@ -216,7 +216,7 @@ for DOCKER_TARGET in "${DOCKER_TARGETS[@]}"; do
216216
TARGET_DOCKER_TAG="${TARGET_DOCKER_TAG}-${DOCKER_TARGET}"
217217
fi
218218
if [ -n "${GH_ACTION}" ]; then
219-
echo "::set-env name=FINAL_DOCKER_TAG::${TARGET_DOCKER_TAG}"
219+
echo "FINAL_DOCKER_TAG=${TARGET_DOCKER_TAG}" >> $GITHUB_ENV
220220
echo "::set-output name=skipped::false"
221221
fi
222222

configuration/configuration.py

Lines changed: 127 additions & 95 deletions
Large diffs are not rendered by default.

configuration/extra.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
####
2+
## This file contains extra configuration options that can't be configured
3+
## directly through environment variables.
4+
####
5+
6+
## Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of
7+
## application errors (assuming correct email settings are provided).
8+
# ADMINS = [
9+
# # ['John Doe', 'jdoe@example.com'],
10+
# ]
11+
12+
13+
## URL schemes that are allowed within links in NetBox
14+
# ALLOWED_URL_SCHEMES = (
15+
# 'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
16+
# )
17+
18+
19+
## NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must
20+
## be provided as a dictionary.
21+
# NAPALM_ARGS = {}
22+
23+
24+
## Enable installed plugins. Add the name of each plugin to the list.
25+
# from netbox.configuration.configuration import PLUGINS
26+
# PLUGINS.append('my_plugin')
27+
28+
## Plugins configuration settings. These settings are used by various plugins that the user may have installed.
29+
## Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings.
30+
# from netbox.configuration.configuration import PLUGINS_CONFIG
31+
# PLUGINS_CONFIG['my_plugin'] = {
32+
# 'foo': 'bar',
33+
# 'buzz': 'bazz'
34+
# }
35+
36+
37+
## Remote authentication support
38+
# REMOTE_AUTH_DEFAULT_PERMISSIONS = {}
39+
40+
41+
## By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the
42+
## class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example:
43+
# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage'
44+
# STORAGE_CONFIG = {
45+
# 'AWS_ACCESS_KEY_ID': 'Key ID',
46+
# 'AWS_SECRET_ACCESS_KEY': 'Secret',
47+
# 'AWS_STORAGE_BUCKET_NAME': 'netbox',
48+
# 'AWS_S3_REGION_NAME': 'eu-west-1',
49+
# }
50+
51+
52+
## This file can contain arbitrary Python code, e.g.:
53+
# from datetime import datetime
54+
# now = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
55+
# BANNER_TOP = f'<marquee width="200px">This instance started on {now}.</marquee>'
Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,84 @@
11
import ldap
2-
import os
32

43
from django_auth_ldap.config import LDAPSearch
54
from importlib import import_module
5+
from os import environ
66

77
# Read secret from file
8-
def read_secret(secret_name):
8+
def _read_secret(secret_name, default=None):
99
try:
1010
f = open('/run/secrets/' + secret_name, 'r', encoding='utf-8')
1111
except EnvironmentError:
12-
return ''
12+
return default
1313
else:
1414
with f:
1515
return f.readline().strip()
1616

1717
# Import and return the group type based on string name
18-
def import_group_type(group_type_name):
18+
def _import_group_type(group_type_name):
1919
mod = import_module('django_auth_ldap.config')
2020
try:
2121
return getattr(mod, group_type_name)()
2222
except:
2323
return None
2424

2525
# Server URI
26-
AUTH_LDAP_SERVER_URI = os.environ.get('AUTH_LDAP_SERVER_URI', '')
26+
AUTH_LDAP_SERVER_URI = environ.get('AUTH_LDAP_SERVER_URI', '')
2727

2828
# The following may be needed if you are binding to Active Directory.
2929
AUTH_LDAP_CONNECTION_OPTIONS = {
3030
ldap.OPT_REFERRALS: 0
3131
}
3232

3333
# Set the DN and password for the NetBox service account.
34-
AUTH_LDAP_BIND_DN = os.environ.get('AUTH_LDAP_BIND_DN', '')
35-
AUTH_LDAP_BIND_PASSWORD = os.environ.get('AUTH_LDAP_BIND_PASSWORD', read_secret('auth_ldap_bind_password'))
34+
AUTH_LDAP_BIND_DN = environ.get('AUTH_LDAP_BIND_DN', '')
35+
AUTH_LDAP_BIND_PASSWORD = _read_secret('auth_ldap_bind_password', environ.get('AUTH_LDAP_BIND_PASSWORD', ''))
3636

3737
# Set a string template that describes any user’s distinguished name based on the username.
38-
AUTH_LDAP_USER_DN_TEMPLATE = os.environ.get('AUTH_LDAP_USER_DN_TEMPLATE', None)
38+
AUTH_LDAP_USER_DN_TEMPLATE = environ.get('AUTH_LDAP_USER_DN_TEMPLATE', None)
3939

4040
# Enable STARTTLS for ldap authentication.
41-
AUTH_LDAP_START_TLS = os.environ.get('AUTH_LDAP_START_TLS', 'False').lower() == 'true'
41+
AUTH_LDAP_START_TLS = environ.get('AUTH_LDAP_START_TLS', 'False').lower() == 'true'
4242

4343
# Include this setting if you want to ignore certificate errors. This might be needed to accept a self-signed cert.
4444
# Note that this is a NetBox-specific setting which sets:
4545
# ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
46-
LDAP_IGNORE_CERT_ERRORS = os.environ.get('LDAP_IGNORE_CERT_ERRORS', 'False').lower() == 'true'
46+
LDAP_IGNORE_CERT_ERRORS = environ.get('LDAP_IGNORE_CERT_ERRORS', 'False').lower() == 'true'
4747

48-
AUTH_LDAP_USER_SEARCH_BASEDN = os.environ.get('AUTH_LDAP_USER_SEARCH_BASEDN', '')
49-
AUTH_LDAP_USER_SEARCH_ATTR = os.environ.get('AUTH_LDAP_USER_SEARCH_ATTR', 'sAMAccountName')
48+
AUTH_LDAP_USER_SEARCH_BASEDN = environ.get('AUTH_LDAP_USER_SEARCH_BASEDN', '')
49+
AUTH_LDAP_USER_SEARCH_ATTR = environ.get('AUTH_LDAP_USER_SEARCH_ATTR', 'sAMAccountName')
5050
AUTH_LDAP_USER_SEARCH = LDAPSearch(AUTH_LDAP_USER_SEARCH_BASEDN,
5151
ldap.SCOPE_SUBTREE,
5252
"(" + AUTH_LDAP_USER_SEARCH_ATTR + "=%(user)s)")
5353

5454
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
5555
# heirarchy.
56-
AUTH_LDAP_GROUP_SEARCH_BASEDN = os.environ.get('AUTH_LDAP_GROUP_SEARCH_BASEDN', '')
57-
AUTH_LDAP_GROUP_SEARCH_CLASS = os.environ.get('AUTH_LDAP_GROUP_SEARCH_CLASS', 'group')
56+
AUTH_LDAP_GROUP_SEARCH_BASEDN = environ.get('AUTH_LDAP_GROUP_SEARCH_BASEDN', '')
57+
AUTH_LDAP_GROUP_SEARCH_CLASS = environ.get('AUTH_LDAP_GROUP_SEARCH_CLASS', 'group')
5858
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(AUTH_LDAP_GROUP_SEARCH_BASEDN, ldap.SCOPE_SUBTREE,
5959
"(objectClass=" + AUTH_LDAP_GROUP_SEARCH_CLASS + ")")
60-
AUTH_LDAP_GROUP_TYPE = import_group_type(os.environ.get('AUTH_LDAP_GROUP_TYPE', 'GroupOfNamesType'))
60+
AUTH_LDAP_GROUP_TYPE = _import_group_type(environ.get('AUTH_LDAP_GROUP_TYPE', 'GroupOfNamesType'))
6161

6262
# Define a group required to login.
63-
AUTH_LDAP_REQUIRE_GROUP = os.environ.get('AUTH_LDAP_REQUIRE_GROUP_DN', '')
63+
AUTH_LDAP_REQUIRE_GROUP = environ.get('AUTH_LDAP_REQUIRE_GROUP_DN', '')
6464

6565
# Define special user types using groups. Exercise great caution when assigning superuser status.
6666
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
67-
"is_active": os.environ.get('AUTH_LDAP_REQUIRE_GROUP_DN', ''),
68-
"is_staff": os.environ.get('AUTH_LDAP_IS_ADMIN_DN', ''),
69-
"is_superuser": os.environ.get('AUTH_LDAP_IS_SUPERUSER_DN', '')
67+
"is_active": environ.get('AUTH_LDAP_REQUIRE_GROUP_DN', ''),
68+
"is_staff": environ.get('AUTH_LDAP_IS_ADMIN_DN', ''),
69+
"is_superuser": environ.get('AUTH_LDAP_IS_SUPERUSER_DN', '')
7070
}
7171

7272
# For more granular permissions, we can map LDAP groups to Django groups.
73-
AUTH_LDAP_FIND_GROUP_PERMS = os.environ.get('AUTH_LDAP_FIND_GROUP_PERMS', 'True').lower() == 'true'
73+
AUTH_LDAP_FIND_GROUP_PERMS = environ.get('AUTH_LDAP_FIND_GROUP_PERMS', 'True').lower() == 'true'
74+
AUTH_LDAP_MIRROR_GROUPS = environ.get('AUTH_LDAP_MIRROR_GROUPS', None).lower() == 'true'
7475

7576
# Cache groups for one hour to reduce LDAP traffic
76-
AUTH_LDAP_CACHE_TIMEOUT = int(os.environ.get('AUTH_LDAP_CACHE_TIMEOUT', 3600))
77+
AUTH_LDAP_CACHE_TIMEOUT = int(environ.get('AUTH_LDAP_CACHE_TIMEOUT', 3600))
7778

7879
# Populate the Django user from the LDAP directory.
7980
AUTH_LDAP_USER_ATTR_MAP = {
80-
"first_name": os.environ.get('AUTH_LDAP_ATTR_FIRSTNAME', 'givenName'),
81-
"last_name": os.environ.get('AUTH_LDAP_ATTR_LASTNAME', 'sn'),
82-
"email": os.environ.get('AUTH_LDAP_ATTR_MAIL', 'mail')
81+
"first_name": environ.get('AUTH_LDAP_ATTR_FIRSTNAME', 'givenName'),
82+
"last_name": environ.get('AUTH_LDAP_ATTR_LASTNAME', 'sn'),
83+
"email": environ.get('AUTH_LDAP_ATTR_MAIL', 'mail')
8384
}

0 commit comments

Comments
 (0)