commit
6d25a54d49
30
.github/workflows/push.yml
vendored
30
.github/workflows/push.yml
vendored
@ -5,10 +5,15 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
- release
|
- release
|
||||||
|
- renovate/**
|
||||||
pull_request:
|
pull_request:
|
||||||
branches-ignore:
|
branches-ignore:
|
||||||
- release
|
- release
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -23,15 +28,17 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: '3.9'
|
python-version: '3.9'
|
||||||
- name: Lint Code Base
|
- name: Lint Code Base
|
||||||
uses: github/super-linter@v5
|
uses: github/super-linter@v6
|
||||||
env:
|
env:
|
||||||
DEFAULT_BRANCH: develop
|
DEFAULT_BRANCH: develop
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
SUPPRESS_POSSUM: true
|
SUPPRESS_POSSUM: true
|
||||||
LINTER_RULES_PATH: /
|
LINTER_RULES_PATH: /
|
||||||
VALIDATE_ALL_CODEBASE: false
|
VALIDATE_ALL_CODEBASE: false
|
||||||
|
VALIDATE_CHECKOV: false
|
||||||
VALIDATE_DOCKERFILE: false
|
VALIDATE_DOCKERFILE: false
|
||||||
VALIDATE_GITLEAKS: false
|
VALIDATE_GITLEAKS: false
|
||||||
|
VALIDATE_JSCPD: false
|
||||||
FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE|configuration/.*)
|
FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE|configuration/.*)
|
||||||
EDITORCONFIG_FILE_NAME: .ecrc
|
EDITORCONFIG_FILE_NAME: .ecrc
|
||||||
DOCKERFILE_HADOLINT_FILE_NAME: .hadolint.yaml
|
DOCKERFILE_HADOLINT_FILE_NAME: .hadolint.yaml
|
||||||
@ -49,35 +56,36 @@ jobs:
|
|||||||
- PRERELEASE=true ./build-latest.sh
|
- PRERELEASE=true ./build-latest.sh
|
||||||
- ./build.sh feature
|
- ./build.sh feature
|
||||||
- ./build.sh develop
|
- ./build.sh develop
|
||||||
platform:
|
os:
|
||||||
- linux/amd64
|
- ubuntu-latest
|
||||||
- linux/arm64
|
- self-hosted
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
env:
|
env:
|
||||||
GH_ACTION: enable
|
GH_ACTION: enable
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
IMAGE_NAMES: docker.io/netboxcommunity/netbox
|
IMAGE_NAMES: docker.io/netboxcommunity/netbox
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
name: Builds new NetBox Docker Images
|
name: Builds new NetBox Docker Images
|
||||||
steps:
|
steps:
|
||||||
- id: git-checkout
|
- id: git-checkout
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- id: qemu-setup
|
|
||||||
name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
- id: buildx-setup
|
- id: buildx-setup
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
- id: arm-buildx-platform
|
||||||
|
name: Set BUILDX_PLATFORM to ARM64
|
||||||
|
if: matrix.os == 'self-hosted'
|
||||||
|
run: |
|
||||||
|
echo "BUILDX_PLATFORM=linux/arm64" >>"${GITHUB_ENV}"
|
||||||
- id: docker-build
|
- id: docker-build
|
||||||
name: Build the image for '${{ matrix.platform }}' with '${{ matrix.build_cmd }}'
|
name: Build the image for '${{ matrix.os }}' with '${{ matrix.build_cmd }}'
|
||||||
run: ${{ matrix.build_cmd }}
|
run: ${{ matrix.build_cmd }}
|
||||||
env:
|
env:
|
||||||
BUILDX_PLATFORM: ${{ matrix.platform }}
|
|
||||||
BUILDX_BUILDER_NAME: ${{ steps.buildx-setup.outputs.name }}
|
BUILDX_BUILDER_NAME: ${{ steps.buildx-setup.outputs.name }}
|
||||||
- id: arm-time-limit
|
- id: arm-time-limit
|
||||||
name: Set Netbox container start_period higher on ARM64
|
name: Set Netbox container start_period higher on ARM64
|
||||||
if: matrix.platform == 'linux/arm64'
|
if: matrix.os == 'self-hosted'
|
||||||
run: |
|
run: |
|
||||||
echo "NETBOX_START_PERIOD=240s" >>"${GITHUB_ENV}"
|
echo "NETBOX_START_PERIOD=240s" >>"${GITHUB_ENV}"
|
||||||
- id: docker-test
|
- id: docker-test
|
||||||
|
10
Dockerfile
10
Dockerfile
@ -31,14 +31,12 @@ RUN export DEBIAN_FRONTEND=noninteractive \
|
|||||||
ARG NETBOX_PATH
|
ARG NETBOX_PATH
|
||||||
COPY ${NETBOX_PATH}/requirements.txt requirements-container.txt /
|
COPY ${NETBOX_PATH}/requirements.txt requirements-container.txt /
|
||||||
RUN \
|
RUN \
|
||||||
# We compile 'psycopg' in the build process
|
|
||||||
sed -i -e '/psycopg/d' /requirements.txt && \
|
|
||||||
# Gunicorn is not needed because we use Nginx Unit
|
# Gunicorn is not needed because we use Nginx Unit
|
||||||
sed -i -e '/gunicorn/d' /requirements.txt && \
|
sed -i -e '/gunicorn/d' /requirements.txt && \
|
||||||
# We need 'social-auth-core[all]' in the Docker image. But if we put it in our own requirements-container.txt
|
# We need 'social-auth-core[all]' in the Docker image. But if we put it in our own requirements-container.txt
|
||||||
# we have potential version conflicts and the build will fail.
|
# we have potential version conflicts and the build will fail.
|
||||||
# That's why we just replace it in the original requirements.txt.
|
# That's why we just replace it in the original requirements.txt.
|
||||||
sed -i -e 's/social-auth-core\[openidconnect\]/social-auth-core\[all\]/g' /requirements.txt && \
|
sed -i -e 's/social-auth-core/social-auth-core\[all\]/g' /requirements.txt && \
|
||||||
/opt/netbox/venv/bin/pip install \
|
/opt/netbox/venv/bin/pip install \
|
||||||
-r /requirements.txt \
|
-r /requirements.txt \
|
||||||
-r /requirements-container.txt
|
-r /requirements-container.txt
|
||||||
@ -69,13 +67,13 @@ RUN export DEBIAN_FRONTEND=noninteractive \
|
|||||||
tini \
|
tini \
|
||||||
&& curl --silent --output /usr/share/keyrings/nginx-keyring.gpg \
|
&& curl --silent --output /usr/share/keyrings/nginx-keyring.gpg \
|
||||||
https://unit.nginx.org/keys/nginx-keyring.gpg \
|
https://unit.nginx.org/keys/nginx-keyring.gpg \
|
||||||
&& echo "deb [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/ubuntu/ lunar unit" \
|
&& echo "deb [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/ubuntu/ mantic unit" \
|
||||||
> /etc/apt/sources.list.d/unit.list \
|
> /etc/apt/sources.list.d/unit.list \
|
||||||
&& apt-get update -qq \
|
&& apt-get update -qq \
|
||||||
&& apt-get install \
|
&& apt-get install \
|
||||||
--yes -qq --no-install-recommends \
|
--yes -qq --no-install-recommends \
|
||||||
unit=1.31.1-1~lunar \
|
unit=1.32.0-1~mantic \
|
||||||
unit-python3.11=1.31.1-1~lunar \
|
unit-python3.11=1.32.0-1~mantic \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY --from=builder /opt/netbox/venv /opt/netbox/venv
|
COPY --from=builder /opt/netbox/venv /opt/netbox/venv
|
||||||
|
@ -34,7 +34,6 @@ There is a more complete [_Getting Started_ guide on our wiki][wiki-getting-star
|
|||||||
git clone -b release https://github.com/netbox-community/netbox-docker.git
|
git clone -b release https://github.com/netbox-community/netbox-docker.git
|
||||||
cd netbox-docker
|
cd netbox-docker
|
||||||
tee docker-compose.override.yml <<EOF
|
tee docker-compose.override.yml <<EOF
|
||||||
version: '3.4'
|
|
||||||
services:
|
services:
|
||||||
netbox:
|
netbox:
|
||||||
ports:
|
ports:
|
||||||
|
4
build.sh
4
build.sh
@ -61,7 +61,7 @@ DOCKERFILE The name of Dockerfile to use.
|
|||||||
${_GREEN}Default:${_CLEAR} Dockerfile
|
${_GREEN}Default:${_CLEAR} Dockerfile
|
||||||
|
|
||||||
DOCKER_FROM The base image to use.
|
DOCKER_FROM The base image to use.
|
||||||
${_GREEN}Default:${_CLEAR} 'ubuntu:23.04'
|
${_GREEN}Default:${_CLEAR} 'ubuntu:23.10'
|
||||||
|
|
||||||
BUILDX_PLATFORMS
|
BUILDX_PLATFORMS
|
||||||
Specifies the platform(s) to build the image for.
|
Specifies the platform(s) to build the image for.
|
||||||
@ -219,7 +219,7 @@ fi
|
|||||||
# Determining the value for DOCKER_FROM
|
# Determining the value for DOCKER_FROM
|
||||||
###
|
###
|
||||||
if [ -z "$DOCKER_FROM" ]; then
|
if [ -z "$DOCKER_FROM" ]; then
|
||||||
DOCKER_FROM="docker.io/ubuntu:23.04"
|
DOCKER_FROM="docker.io/ubuntu:23.10"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
###
|
###
|
||||||
|
@ -86,6 +86,9 @@ REDIS = {
|
|||||||
'tasks': {
|
'tasks': {
|
||||||
'HOST': environ.get('REDIS_HOST', 'localhost'),
|
'HOST': environ.get('REDIS_HOST', 'localhost'),
|
||||||
'PORT': _environ_get_and_map('REDIS_PORT', 6379, _AS_INT),
|
'PORT': _environ_get_and_map('REDIS_PORT', 6379, _AS_INT),
|
||||||
|
'SENTINELS': [tuple(uri.split(':')) for uri in _environ_get_and_map('REDIS_SENTINELS', '', _AS_LIST) if uri != ''],
|
||||||
|
'SENTINEL_SERVICE': environ.get('REDIS_SENTINEL_SERVICE', 'default'),
|
||||||
|
'SENTINEL_TIMEOUT': _environ_get_and_map('REDIS_SENTINEL_TIMEOUT', 10, _AS_INT),
|
||||||
'USERNAME': environ.get('REDIS_USERNAME', ''),
|
'USERNAME': environ.get('REDIS_USERNAME', ''),
|
||||||
'PASSWORD': _read_secret('redis_password', environ.get('REDIS_PASSWORD', '')),
|
'PASSWORD': _read_secret('redis_password', environ.get('REDIS_PASSWORD', '')),
|
||||||
'DATABASE': _environ_get_and_map('REDIS_DATABASE', 0, _AS_INT),
|
'DATABASE': _environ_get_and_map('REDIS_DATABASE', 0, _AS_INT),
|
||||||
@ -95,6 +98,8 @@ REDIS = {
|
|||||||
'caching': {
|
'caching': {
|
||||||
'HOST': environ.get('REDIS_CACHE_HOST', environ.get('REDIS_HOST', 'localhost')),
|
'HOST': environ.get('REDIS_CACHE_HOST', environ.get('REDIS_HOST', 'localhost')),
|
||||||
'PORT': _environ_get_and_map('REDIS_CACHE_PORT', environ.get('REDIS_PORT', '6379'), _AS_INT),
|
'PORT': _environ_get_and_map('REDIS_CACHE_PORT', environ.get('REDIS_PORT', '6379'), _AS_INT),
|
||||||
|
'SENTINELS': [tuple(uri.split(':')) for uri in _environ_get_and_map('REDIS_CACHE_SENTINELS', '', _AS_LIST) if uri != ''],
|
||||||
|
'SENTINEL_SERVICE': environ.get('REDIS_CACHE_SENTINEL_SERVICE', environ.get('REDIS_SENTINEL_SERVICE', 'default')),
|
||||||
'USERNAME': environ.get('REDIS_CACHE_USERNAME', environ.get('REDIS_USERNAME', '')),
|
'USERNAME': environ.get('REDIS_CACHE_USERNAME', environ.get('REDIS_USERNAME', '')),
|
||||||
'PASSWORD': _read_secret('redis_cache_password', environ.get('REDIS_CACHE_PASSWORD', environ.get('REDIS_PASSWORD', ''))),
|
'PASSWORD': _read_secret('redis_cache_password', environ.get('REDIS_CACHE_PASSWORD', environ.get('REDIS_PASSWORD', ''))),
|
||||||
'DATABASE': _environ_get_and_map('REDIS_CACHE_DATABASE', '1', _AS_INT),
|
'DATABASE': _environ_get_and_map('REDIS_CACHE_DATABASE', '1', _AS_INT),
|
||||||
@ -183,6 +188,13 @@ EMAIL = {
|
|||||||
if 'ENFORCE_GLOBAL_UNIQUE' in environ:
|
if 'ENFORCE_GLOBAL_UNIQUE' in environ:
|
||||||
ENFORCE_GLOBAL_UNIQUE = _environ_get_and_map('ENFORCE_GLOBAL_UNIQUE', None, _AS_BOOL)
|
ENFORCE_GLOBAL_UNIQUE = _environ_get_and_map('ENFORCE_GLOBAL_UNIQUE', None, _AS_BOOL)
|
||||||
|
|
||||||
|
# By default, netbox sends census reporting data using a single HTTP request each time a worker starts.
|
||||||
|
# This data enables the project maintainers to estimate how many NetBox deployments exist and track the adoption of new versions over time.
|
||||||
|
# The only data reported by this function are the NetBox version, Python version, and a pseudorandom unique identifier.
|
||||||
|
# To opt out of census reporting, set CENSUS_REPORTING_ENABLED to False.
|
||||||
|
if 'CENSUS_REPORTING_ENABLED' in environ:
|
||||||
|
CENSUS_REPORTING_ENABLED = _environ_get_and_map('CENSUS_REPORTING_ENABLED', None, _AS_BOOL)
|
||||||
|
|
||||||
# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and
|
# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and
|
||||||
# by anonymous users. List models in the form `<app>.<model>`. Add '*' to this list to exempt all models.
|
# by anonymous users. List models in the form `<app>.<model>`. Add '*' to this list to exempt all models.
|
||||||
EXEMPT_VIEW_PERMISSIONS = _environ_get_and_map('EXEMPT_VIEW_PERMISSIONS', '', _AS_LIST)
|
EXEMPT_VIEW_PERMISSIONS = _environ_get_and_map('EXEMPT_VIEW_PERMISSIONS', '', _AS_LIST)
|
||||||
@ -300,6 +312,23 @@ CSRF_TRUSTED_ORIGINS = _environ_get_and_map('CSRF_TRUSTED_ORIGINS', '', _AS_LIST
|
|||||||
# The name to use for the session cookie.
|
# The name to use for the session cookie.
|
||||||
SESSION_COOKIE_NAME = environ.get('SESSION_COOKIE_NAME', 'sessionid')
|
SESSION_COOKIE_NAME = environ.get('SESSION_COOKIE_NAME', 'sessionid')
|
||||||
|
|
||||||
|
# If true, the `includeSubDomains` directive will be included in the HTTP Strict Transport Security (HSTS) header.
|
||||||
|
# This directive instructs the browser to apply the HSTS policy to all subdomains of the current domain.
|
||||||
|
SECURE_HSTS_INCLUDE_SUBDOMAINS = _environ_get_and_map('SECURE_HSTS_INCLUDE_SUBDOMAINS', 'False', _AS_BOOL)
|
||||||
|
|
||||||
|
# If true, the `preload` directive will be included in the HTTP Strict Transport Security (HSTS) header.
|
||||||
|
# This directive instructs the browser to preload the site in HTTPS. Browsers that use the HSTS preload list will force the
|
||||||
|
# site to be accessed via HTTPS even if the user types HTTP in the address bar.
|
||||||
|
SECURE_HSTS_PRELOAD = _environ_get_and_map('SECURE_HSTS_PRELOAD', 'False', _AS_BOOL)
|
||||||
|
|
||||||
|
# If set to a non-zero integer value, the SecurityMiddleware sets the HTTP Strict Transport Security (HSTS) header on all
|
||||||
|
# responses that do not already have it. This will instruct the browser that the website must be accessed via HTTPS,
|
||||||
|
# blocking any HTTP request.
|
||||||
|
SECURE_HSTS_SECONDS = _environ_get_and_map('SECURE_HSTS_SECONDS', 0, _AS_INT)
|
||||||
|
|
||||||
|
# If true, all non-HTTPS requests will be automatically redirected to use HTTPS.
|
||||||
|
SECURE_SSL_REDIRECT = _environ_get_and_map('SECURE_SSL_REDIRECT', 'False', _AS_BOOL)
|
||||||
|
|
||||||
# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use
|
# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use
|
||||||
# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only
|
# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only
|
||||||
# database access.) Note that the user as which NetBox runs must have read and write permissions to this path.
|
# database access.) Note that the user as which NetBox runs must have read and write permissions to this path.
|
||||||
@ -308,11 +337,3 @@ SESSION_FILE_PATH = environ.get('SESSION_FILE_PATH', environ.get('SESSIONS_ROOT'
|
|||||||
# Time zone (default: UTC)
|
# Time zone (default: UTC)
|
||||||
TIME_ZONE = environ.get('TIME_ZONE', 'UTC')
|
TIME_ZONE = environ.get('TIME_ZONE', 'UTC')
|
||||||
|
|
||||||
# Date/time formatting. See the following link for supported formats:
|
|
||||||
# https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date
|
|
||||||
DATE_FORMAT = environ.get('DATE_FORMAT', 'N j, Y')
|
|
||||||
SHORT_DATE_FORMAT = environ.get('SHORT_DATE_FORMAT', 'Y-m-d')
|
|
||||||
TIME_FORMAT = environ.get('TIME_FORMAT', 'g:i a')
|
|
||||||
SHORT_TIME_FORMAT = environ.get('SHORT_TIME_FORMAT', 'H:i:s')
|
|
||||||
DATETIME_FORMAT = environ.get('DATETIME_FORMAT', 'N j, Y g:i a')
|
|
||||||
SHORT_DATETIME_FORMAT = environ.get('SHORT_DATETIME_FORMAT', 'Y-m-d H:i')
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
version: '3.4'
|
|
||||||
services:
|
services:
|
||||||
netbox:
|
netbox:
|
||||||
ports:
|
ports:
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
version: '3.4'
|
|
||||||
services:
|
services:
|
||||||
netbox:
|
netbox:
|
||||||
ports:
|
ports:
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
version: '3.4'
|
|
||||||
services:
|
services:
|
||||||
netbox: &netbox
|
netbox: &netbox
|
||||||
image: ${IMAGE-netboxcommunity/netbox:latest}
|
image: ${IMAGE-netboxcommunity/netbox:latest}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
version: '3.4'
|
|
||||||
services:
|
services:
|
||||||
netbox: &netbox
|
netbox: &netbox
|
||||||
image: docker.io/netboxcommunity/netbox:${VERSION-v3.7-2.8.0}
|
image: docker.io/netboxcommunity/netbox:${VERSION-v4.0-2.9.0}
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
@ -72,8 +72,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
./manage.py shell --interface python <<END
|
./manage.py shell --interface python <<END
|
||||||
from django.contrib.auth.models import User
|
from users.models import Token, User
|
||||||
from users.models import Token
|
|
||||||
if not User.objects.filter(username='${SUPERUSER_NAME}'):
|
if not User.objects.filter(username='${SUPERUSER_NAME}'):
|
||||||
u = User.objects.create_superuser('${SUPERUSER_NAME}', '${SUPERUSER_EMAIL}', '${SUPERUSER_PASSWORD}')
|
u = User.objects.create_superuser('${SUPERUSER_NAME}', '${SUPERUSER_EMAIL}', '${SUPERUSER_PASSWORD}')
|
||||||
Token.objects.create(user=u, key='${SUPERUSER_API_TOKEN}')
|
Token.objects.create(user=u, key='${SUPERUSER_API_TOKEN}')
|
||||||
@ -87,7 +86,7 @@ from users.models import Token
|
|||||||
try:
|
try:
|
||||||
old_default_token = Token.objects.get(key="0123456789abcdef0123456789abcdef01234567")
|
old_default_token = Token.objects.get(key="0123456789abcdef0123456789abcdef01234567")
|
||||||
if old_default_token:
|
if old_default_token:
|
||||||
print("⚠️ Warning: You have the old default admin token in your database. This token is widely known; please remove it.")
|
print("⚠️ Warning: You have the old default admin API token in your database. This token is widely known; please remove it. Log in as your superuser and check API Tokens in your user menu.")
|
||||||
except Token.DoesNotExist:
|
except Token.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
END
|
END
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
django-auth-ldap==4.6.0
|
django-auth-ldap==4.8.0
|
||||||
django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.14.2
|
django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.14.3
|
||||||
dulwich==0.21.7
|
dulwich==0.22.1
|
||||||
psycopg[c,pool]==3.1.16
|
python3-saml==1.16.0 --no-binary lxml
|
||||||
python3-saml==1.16.0
|
sentry-sdk==2.1.1
|
||||||
|
Loading…
Reference in New Issue
Block a user