diff --git a/.dockerignore b/.dockerignore index 00fd8b8..0a0ae31 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,10 +1,10 @@ -.git -.github -.travis.yml +.git* *.md -env build* -docker-compose.override.yml +docker-compose* +env +test-configuration .netbox/.git* -.netbox/.travis.yml +.netbox/contrib .netbox/scripts +.netbox/upgrade.sh diff --git a/Dockerfile b/Dockerfile index 60589c9..11fa4ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,7 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive \ ARG NETBOX_PATH COPY ${NETBOX_PATH}/requirements.txt requirements-container.txt / -RUN sed -i -e '/psycopg2-binary/d' /requirements.txt && \ +RUN \ + # We compile 'psycopg2' in the build process + sed -i -e '/psycopg2-binary/d' /requirements.txt && \ + # Gunicorn is not needed because we use Nginx Unit + 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 have potential version conflicts and the build will fail. # That's why we just replace it in the original requirements.txt. @@ -93,11 +97,11 @@ WORKDIR /opt/netbox/netbox # Must set permissions for '/opt/netbox/netbox/media' directory # to g+w so that pictures can be uploaded to netbox. RUN mkdir -p static /opt/unit/state/ /opt/unit/tmp/ \ - && chown -R unit:root media /opt/unit/ \ - && chmod -R g+w media /opt/unit/ \ - && cd /opt/netbox/ && SECRET_KEY="dummy" /opt/netbox/venv/bin/python -m mkdocs build \ + && chown -R unit:root /opt/unit/ media reports scripts \ + && chmod -R g+w /opt/unit/ media reports scripts \ + && cd /opt/netbox/ && SECRET_KEY="dummyKeyWithMinimumLength-------------------------" /opt/netbox/venv/bin/python -m mkdocs build \ --config-file /opt/netbox/mkdocs.yml --site-dir /opt/netbox/netbox/project-static/docs/ \ - && SECRET_KEY="dummy" /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py collectstatic --no-input + && SECRET_KEY="dummyKeyWithMinimumLength-------------------------" /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py collectstatic --no-input ENV LANG=C.utf8 PATH=/opt/netbox/venv/bin:$PATH ENTRYPOINT [ "/usr/bin/tini", "--" ] diff --git a/README.md b/README.md index 3613cb9..e472945 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ For each of the above tag, there is an extra tag: ## Documentation Please refer [to our wiki on GitHub][netbox-docker-wiki] for further information on how to use the NetBox Docker image properly. -The wiki covers advanced topics such as using files for secrets, configuring TLS, deployment to Kubernetes, monitoring and configuring NAPALM and LDAP. +The wiki covers advanced topics such as using files for secrets, configuring TLS, deployment to Kubernetes, monitoring and configuring LDAP. Our wiki is a community effort. Feel free to correct errors, update outdated information or provide additional guides and insights. diff --git a/VERSION b/VERSION index aedc15b..e70b452 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5.3 +2.6.0 diff --git a/build-functions/get-public-image-config.sh b/build-functions/get-public-image-config.sh index 70c292c..0a19c3f 100644 --- a/build-functions/get-public-image-config.sh +++ b/build-functions/get-public-image-config.sh @@ -1,5 +1,11 @@ #!/bin/bash +check_if_tags_exists() { + local image=$1 + local tag=$2 + skopeo list-tags "docker://$image" | jq -r ".Tags | contains([\"$tag\"])" +} + get_image_label() { local label=$1 local image=$2 diff --git a/build.sh b/build.sh index d1c08e4..5bbaf4d 100755 --- a/build.sh +++ b/build.sh @@ -139,7 +139,8 @@ fi # Check if we have everything needed for the build source ./build-functions/check-commands.sh - +# Load all build functions +source ./build-functions/get-public-image-config.sh source ./build-functions/gh-functions.sh IMAGE_NAMES="${IMAGE_NAMES-docker.io/netboxcommunity/netbox}" @@ -309,19 +310,22 @@ gh_env "FINAL_DOCKER_TAG=${IMAGE_NAME_TAGS[0]}" ### # Checking if the build is necessary, # meaning build only if one of those values changed: +# - a new tag is beeing created # - base image digest # - netbox git ref (Label: netbox.git-ref) # - netbox-docker git ref (Label: org.opencontainers.image.revision) ### -# Load information from registry (only for docker.io) +# Load information from registry (only for first registry in "IMAGE_NAMES") SHOULD_BUILD="false" BUILD_REASON="" if [ -z "${GH_ACTION}" ]; then # Asuming non Github builds should always proceed SHOULD_BUILD="true" BUILD_REASON="${BUILD_REASON} interactive" +elif [ "false" == "$(check_if_tags_exists "${IMAGE_NAMES[0]}" "$TARGET_DOCKER_TAG")" ]; then + SHOULD_BUILD="true" + BUILD_REASON="${BUILD_REASON} newtag" else - source ./build-functions/get-public-image-config.sh echo "Checking labels for '${FINAL_DOCKER_TAG}'" BASE_LAST_LAYER=$(get_image_last_layer "${DOCKER_FROM}") OLD_BASE_LAST_LAYER=$(get_image_label netbox.last-base-image-layer "${FINAL_DOCKER_TAG}") diff --git a/configuration/configuration.py b/configuration/configuration.py index 18bfd01..5185735 100644 --- a/configuration/configuration.py +++ b/configuration/configuration.py @@ -136,10 +136,6 @@ if 'BANNER_BOTTOM' in environ: if 'BANNER_LOGIN' in environ: BANNER_LOGIN = environ.get('BANNER_LOGIN', None) -# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set: -# BASE_PATH = 'netbox/' -BASE_PATH = environ.get('BASE_PATH', '') - # Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90) if 'CHANGELOG_RETENTION' in environ: CHANGELOG_RETENTION = _environ_get_and_map('CHANGELOG_RETENTION', None, _AS_INT) @@ -239,20 +235,6 @@ MEDIA_ROOT = environ.get('MEDIA_ROOT', join(_BASE_DIR, 'media')) # Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics' METRICS_ENABLED = _environ_get_and_map('METRICS_ENABLED', 'False', _AS_BOOL) -# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM. -if 'NAPALM_USERNAME' in environ: - NAPALM_USERNAME = environ.get('NAPALM_USERNAME', None) -if 'NAPALM_PASSWORD' in environ: - NAPALM_PASSWORD = _read_secret('napalm_password', environ.get('NAPALM_PASSWORD', None)) - -# NAPALM timeout (in seconds). (Default: 30) -if 'NAPALM_TIMEOUT' in environ: - NAPALM_TIMEOUT = _environ_get_and_map('NAPALM_TIMEOUT', None, _AS_INT) - -# # NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must -# # be provided as a dictionary. -# NAPALM_ARGS = None - # Determine how many objects to display per page within a list. (Default: 50) if 'PAGINATE_COUNT' in environ: PAGINATE_COUNT = _environ_get_and_map('PAGINATE_COUNT', None, _AS_INT) @@ -301,17 +283,9 @@ REMOTE_AUTH_DEFAULT_GROUPS = _environ_get_and_map('REMOTE_AUTH_DEFAULT_GROUPS', RELEASE_CHECK_URL = environ.get('RELEASE_CHECK_URL', None) # RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases' -# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of -# this setting is derived from the installed location. -REPORTS_ROOT = environ.get('REPORTS_ROOT', '/etc/netbox/reports') - # Maximum execution time for background tasks, in seconds. RQ_DEFAULT_TIMEOUT = _environ_get_and_map('RQ_DEFAULT_TIMEOUT', 300, _AS_INT) -# The file path where custom scripts will be stored. A trailing slash is not needed. Note that the default value of -# this setting is derived from the installed location. -SCRIPTS_ROOT = environ.get('SCRIPTS_ROOT', '/etc/netbox/scripts') - # The name to use for the csrf token cookie. CSRF_COOKIE_NAME = environ.get('CSRF_COOKIE_NAME', 'csrftoken') diff --git a/configuration/extra.py b/configuration/extra.py index 46f1877..8bd1337 100644 --- a/configuration/extra.py +++ b/configuration/extra.py @@ -15,12 +15,6 @@ # 'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp', # ) - -## NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must -## be provided as a dictionary. -# NAPALM_ARGS = {} - - ## Enable installed plugins. Add the name of each plugin to the list. # from netbox.configuration.configuration import PLUGINS # PLUGINS.append('my_plugin') diff --git a/docker-compose.yml b/docker-compose.yml index c1038ca..5932152 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.4' services: netbox: &netbox - image: docker.io/netboxcommunity/netbox:${VERSION-v3.4-2.5.3} + image: docker.io/netboxcommunity/netbox:${VERSION-v3.4-2.6.0} depends_on: - postgres - redis @@ -15,9 +15,9 @@ services: test: "curl -f http://localhost:8080/api/ || exit 1" volumes: - ./configuration:/etc/netbox/config:z,ro - - ./reports:/etc/netbox/reports:z,ro - - ./scripts:/etc/netbox/scripts:z,ro - - netbox-media-files:/opt/netbox/netbox/media:z + - netbox-media-files:/opt/netbox/netbox/media:z,rw + - netbox-reports-files:/opt/netbox/netbox/reports:z,rw + - netbox-scripts-files:/opt/netbox/netbox/scripts:z,rw netbox-worker: <<: *netbox depends_on: @@ -77,7 +77,11 @@ volumes: driver: local netbox-postgres-data: driver: local - netbox-redis-data: - driver: local netbox-redis-cache-data: driver: local + netbox-redis-data: + driver: local + netbox-reports-files: + driver: local + netbox-scripts-files: + driver: local diff --git a/env/netbox.env b/env/netbox.env index 2691a04..9e490d0 100644 --- a/env/netbox.env +++ b/env/netbox.env @@ -29,6 +29,6 @@ REDIS_INSECURE_SKIP_TLS_VERIFY=false REDIS_PASSWORD=H733Kdjndks81 REDIS_SSL=false RELEASE_CHECK_URL=https://api.github.com/repos/netbox-community/netbox/releases -SECRET_KEY=r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj +SECRET_KEY=r(m)9nLGnz$(_q3N4z1k(EFsMCjjjzx08x9VhNVcfd%6RF#r!6DE@+V5Zk2X SKIP_SUPERUSER=true WEBHOOKS_ENABLED=true diff --git a/reports/devices.py.example b/reports/devices.py.example deleted file mode 100644 index 670eeb6..0000000 --- a/reports/devices.py.example +++ /dev/null @@ -1,46 +0,0 @@ -from dcim.choices import DeviceStatusChoices -from dcim.models import ConsolePort, Device, PowerPort -from extras.reports import Report - - -class DeviceConnectionsReport(Report): - description = "Validate the minimum physical connections for each device" - - def test_console_connection(self): - - # Check that every console port for every active device has a connection defined. - active = DeviceStatusChoices.STATUS_ACTIVE - for console_port in ConsolePort.objects.prefetch_related('device').filter(device__status=active): - if console_port.connected_endpoint is None: - self.log_failure( - console_port.device, - "No console connection defined for {}".format(console_port.name) - ) - elif not console_port.connection_status: - self.log_warning( - console_port.device, - "Console connection for {} marked as planned".format(console_port.name) - ) - else: - self.log_success(console_port.device) - - def test_power_connections(self): - - # Check that every active device has at least two connected power supplies. - for device in Device.objects.filter(status=DeviceStatusChoices.STATUS_ACTIVE): - connected_ports = 0 - for power_port in PowerPort.objects.filter(device=device): - if power_port.connected_endpoint is not None: - connected_ports += 1 - if not power_port.connection_status: - self.log_warning( - device, - "Power connection for {} marked as planned".format(power_port.name) - ) - if connected_ports < 2: - self.log_failure( - device, - "{} connected power supplies found (2 needed)".format(connected_ports) - ) - else: - self.log_success(device) diff --git a/requirements-container.txt b/requirements-container.txt index 2fd446a..e00569f 100644 --- a/requirements-container.txt +++ b/requirements-container.txt @@ -1,5 +1,4 @@ -django-auth-ldap==4.2.0 +django-auth-ldap==4.3.0 django-storages[azure,boto3,dropbox,google,libcloud,sftp]==1.13.2 -napalm==4.0.0 psycopg2==2.9.6 python3-saml==1.15.0 diff --git a/scripts/__init__.py b/scripts/__init__.py deleted file mode 100644 index e69de29..0000000