From 9f461a17aa7e52acf081398efe78fb3a33cdeeb3 Mon Sep 17 00:00:00 2001 From: Chris Russell Date: Thu, 6 Jun 2024 01:17:34 +0100 Subject: [PATCH 1/9] various 4.x fixes --- README.md | 7 +- docker-develop/Dockerfile | 28 +++ docker-develop/README.md | 12 ++ docker-develop/configuration.py | 199 ++++++++++++++++++ docker-develop/dev.env | 18 ++ docker-develop/docker-compose.yml | 47 +++++ docker-develop/set-superuser.sh | 4 + netbox_floorplan/__init__.py | 8 +- netbox_floorplan/admin.py | 9 - .../static/netbox_floorplan/floorplan/edit.js | 1 + .../netbox_floorplan/floorplan_edit.html | 36 ++-- .../netbox_floorplan/floorplan_list.html | 1 + .../netbox_floorplan/floorplan_view.html | 10 +- netbox_floorplan/version.py | 2 +- setup.py | 2 +- 15 files changed, 343 insertions(+), 41 deletions(-) create mode 100644 docker-develop/Dockerfile create mode 100644 docker-develop/README.md create mode 100644 docker-develop/configuration.py create mode 100644 docker-develop/dev.env create mode 100644 docker-develop/docker-compose.yml create mode 100755 docker-develop/set-superuser.sh diff --git a/README.md b/README.md index fa1c7fb..21cf1d9 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,11 @@ A netbox plugin providing floorplan mapping capability for locations and sites ## Compatibility -| | | +| NetBox Version | Plugin Version | |-------------|-----------| -| NetBox 3.5 | >= 0.3.2 | -| NetBox 3.6 | >= 0.3.2 | +| 3.5 | >= 0.3.2 | +| 3.6 | >= 0.3.2 | +| >4.0.2 | 0.4.0 | ## Installing diff --git a/docker-develop/Dockerfile b/docker-develop/Dockerfile new file mode 100644 index 0000000..e9f69ce --- /dev/null +++ b/docker-develop/Dockerfile @@ -0,0 +1,28 @@ +ARG python_ver=3.12 +FROM python:${python_ver} + +ARG netbox_ver=master +ENV PYTHONUNBUFFERED 1 + +RUN mkdir -p /opt + +RUN pip install --upgrade pip + +# ------------------------------------------------------------------------------------- +# Install NetBox +# ------------------------------------------------------------------------------------- +RUN git clone --single-branch --branch ${netbox_ver} https://github.com/netbox-community/netbox.git /opt/netbox/ && \ + cd /opt/netbox/ && \ + pip install -r /opt/netbox/requirements.txt + +# ------------------------------------------------------------------------------------- +# Install Netbox Plugin +# ------------------------------------------------------------------------------------- +RUN mkdir -p /source +WORKDIR /source +COPY . /source + +#RUN pip install -r requirements.txt +RUN python -m pip install --editable . + +WORKDIR /opt/netbox/netbox/ diff --git a/docker-develop/README.md b/docker-develop/README.md new file mode 100644 index 0000000..505d88b --- /dev/null +++ b/docker-develop/README.md @@ -0,0 +1,12 @@ + +# development environment + +docker compose pull +docker compose build +docker compose up + +docker exec -it docker-develop-netbox-1 /opt/netbox/netbox/manage.py makemigrations netbox_floorplan_plugin + +docker exec -it docker-develop-netbox-1 /opt/netbox/netbox/manage.py makemigrations migrate + +docker exec -it docker-develop-netbox-1 /opt/netbox/netbox/manage.py createsuperuser diff --git a/docker-develop/configuration.py b/docker-develop/configuration.py new file mode 100644 index 0000000..3db53fc --- /dev/null +++ b/docker-develop/configuration.py @@ -0,0 +1,199 @@ +"""NetBox configuration file.""" +import os + +# For reference see http://netbox.readthedocs.io/en/latest/configuration/mandatory-settings/ +# Based on https://github.com/digitalocean/netbox/blob/develop/netbox/netbox/configuration.example.py + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +######################### +# # +# 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 = { + "NAME": os.environ.get("DB_NAME", "netbox"), # Database name + "USER": os.environ.get("DB_USER", ""), # PostgreSQL username + "PASSWORD": os.environ.get("DB_PASSWORD", ""), + # PostgreSQL password + "HOST": os.environ.get("DB_HOST", "localhost"), # Database server + "PORT": os.environ.get("DB_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. +# 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", "") + +# Redis database settings. The Redis database is used for caching and background processing such as webhooks +# Seperate sections for webhooks and caching allow for connecting to seperate Redis instances/datbases if desired. +# Full connection details are required in both sections, even if they are the same. +REDIS = { + "caching": { + "HOST": os.environ.get("REDIS_HOST", "redis"), + "PORT": int(os.environ.get("REDIS_PORT", 6379)), + "PASSWORD": os.environ.get("REDIS_PASSWORD", ""), + "DATABASE": 1, + "DEFAULT_TIMEOUT": 300, + "SSL": bool(os.environ.get("REDIS_SSL", False)), + }, + "tasks": { + "HOST": os.environ.get("REDIS_HOST", "redis"), + "PORT": int(os.environ.get("REDIS_PORT", 6379)), + "PASSWORD": os.environ.get("REDIS_PASSWORD", ""), + "DATABASE": 0, + "DEFAULT_TIMEOUT": 300, + "SSL": bool(os.environ.get("REDIS_SSL", False)), + }, +} + + +######################### +# # +# 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'], +] + +# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same +# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP. +BANNER_TOP = os.environ.get("BANNER_TOP", None) +BANNER_BOTTOM = os.environ.get("BANNER_BOTTOM", None) + +# Text to include on the login page above the login form. HTML is allowed. +BANNER_LOGIN = os.environ.get("BANNER_LOGIN", "") + +# 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", "") + +# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90) +CHANGELOG_RETENTION = int(os.environ.get("CHANGELOG_RETENTION", 0)) + +# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be +# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or +# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers +CORS_ORIGIN_ALLOW_ALL = True +CORS_ORIGIN_WHITELIST = [] +CORS_ORIGIN_REGEX_WHITELIST = [] + +# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal +# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging +# on a production system. +DEBUG = True +DEVELOPER = True + +# Email settings +EMAIL = { + "SERVER": "localhost", + "PORT": 25, + "USERNAME": "", + "PASSWORD": "", + "TIMEOUT": 10, + "FROM_EMAIL": "", +} + +# Enforcement of unique IP space can be toggled on a per-VRF basis. +# To enforce unique IP space within the global table (all prefixes and IP addresses not assigned to a VRF), +# set ENFORCE_GLOBAL_UNIQUE to True. +ENFORCE_GLOBAL_UNIQUE = False + +# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: +# https://docs.djangoproject.com/en/1.11/topics/logging/ +LOGGING = {} + +# 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 = 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) + +# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g. +# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request +# all objects by specifying "?limit=0". +MAX_PAGE_SIZE = int(os.environ.get("MAX_PAGE_SIZE", 1000)) + +# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that +# the default value of this setting is derived from the installed location. +MEDIA_ROOT = os.environ.get("MEDIA_ROOT", os.path.join(BASE_DIR, "media")) + +NAPALM_USERNAME = os.environ.get("NAPALM_USERNAME", "") +NAPALM_PASSWORD = os.environ.get("NAPALM_PASSWORD", "") + +# NAPALM timeout (in seconds). (Default: 30) +NAPALM_TIMEOUT = os.environ.get("NAPALM_TIMEOUT", 30) + +# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must +# be provided as a dictionary. +NAPALM_ARGS = { + "secret": NAPALM_PASSWORD, + # Include any additional args here +} + +# Determine how many objects to display per page within a list. (Default: 50) +PAGINATE_COUNT = os.environ.get("PAGINATE_COUNT", 50) + +# Enable installed plugins. Add the name of each plugin to the list. +PLUGINS = ["netbox_floorplan"] + +# Plugins configuration settings. These settings are used by various plugins that the user may have installed. +# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings. +# PLUGINS_CONFIG = {} + +# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to +# prefer IPv4 instead. +PREFER_IPV4 = os.environ.get("PREFER_IPV4", False) + +# Remote authentication support +REMOTE_AUTH_ENABLED = False +#REMOTE_AUTH_BACKEND = "utilities.auth_backends.RemoteUserBackend" +REMOTE_AUTH_BACKEND = "netbox.authentication.RemoteUserBackend" +REMOTE_AUTH_HEADER = "HTTP_REMOTE_USER" +REMOTE_AUTH_AUTO_CREATE_USER = True +REMOTE_AUTH_DEFAULT_GROUPS = [] +REMOTE_AUTH_DEFAULT_PERMISSIONS = [] + +# This determines how often the GitHub API is called to check the latest release of NetBox. Must be at least 1 hour. +RELEASE_CHECK_TIMEOUT = 24 * 3600 + +# This repository is used to check whether there is a new release of NetBox available. Set to None to disable the +# version check or use the URL below to check for release in the official NetBox repository. +RELEASE_CHECK_URL = None +# RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases' + +SESSION_FILE_PATH = None + +# 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 = os.environ.get("REPORTS_ROOT", os.path.join(BASE_DIR, "reports")) + +# 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/docker-develop/dev.env b/docker-develop/dev.env new file mode 100644 index 0000000..d726d98 --- /dev/null +++ b/docker-develop/dev.env @@ -0,0 +1,18 @@ +ALLOWED_HOSTS=* +DB_NAME=netbox +DB_USER=netbox +DB_PASSWORD=sajdhasdj213jh1ss +PGPASSWORD=sajdhasdj213jh1ss +DB_HOST=postgres +NAPALM_TIMEOUT=5 +MAX_PAGE_SIZE=0 +SECRET_KEY=QT4LOkwlMv66m5lN6j7z1gGOKpNsG5SWbB6p4PTAlLg2QT4LOkwlMv66m5lN6j7z1gGOKpNsG5SWbB6p4PTAlLg2 +POSTGRES_USER=netbox +POSTGRES_PASSWORD=sajdhasdj213jh1ss +POSTGRES_DB=netbox +CHANGELOG_RETENTION=0 +REDIS_HOST=redis +REDIS_PORT=6379 +# Uncomment REDIS_SSL if using SSL +# REDIS_SSL=True +REDIS_PASSWORD=sajdhasdj213jh1ss diff --git a/docker-develop/docker-compose.yml b/docker-develop/docker-compose.yml new file mode 100644 index 0000000..39645cd --- /dev/null +++ b/docker-develop/docker-compose.yml @@ -0,0 +1,47 @@ +--- +services: + netbox: + build: + context: ../ + dockerfile: docker-develop/Dockerfile + command: > + sh -c "python manage.py migrate && + python manage.py runserver 0.0.0.0:8000" + ports: + - '8000:8000' + depends_on: + - postgres + - redis + env_file: + - ./dev.env + volumes: + - ./configuration.py:/opt/netbox/netbox/netbox/configuration.py + - ../netbox_floorplan:/source/netbox_floorplan + tty: true + worker: + build: + context: ../ + dockerfile: docker-develop/Dockerfile + command: sh -c "python manage.py rqworker" + depends_on: + - netbox + env_file: + - ./dev.env + volumes: + - ./configuration.py:/opt/netbox/netbox/netbox/configuration.py + - ../netbox_floorplan:/source/netbox_floorplan + tty: true + postgres: + image: postgres:16 + env_file: dev.env + volumes: + - pgdata_netbox_floorplan:/var/lib/postgresql/data + redis: + image: redis:7-alpine + command: + - sh + - -c # this is to evaluate the $REDIS_PASSWORD from the env + - redis-server --appendonly yes --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose + env_file: ./dev.env +volumes: + pgdata_netbox_floorplan: diff --git a/docker-develop/set-superuser.sh b/docker-develop/set-superuser.sh new file mode 100755 index 0000000..dda4f77 --- /dev/null +++ b/docker-develop/set-superuser.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker exec -it docker-develop-netbox-1 /opt/netbox/netbox/manage.py createsuperuser + diff --git a/netbox_floorplan/__init__.py b/netbox_floorplan/__init__.py index 7688fc9..88ee2f3 100644 --- a/netbox_floorplan/__init__.py +++ b/netbox_floorplan/__init__.py @@ -1,13 +1,13 @@ -from extras.plugins import PluginConfig +from netbox.plugins import PluginConfig class FloorplanConfig(PluginConfig): name = "netbox_floorplan" verbose_name = "Netbox Floorplan" description = "" - version = "0.3.6" + version = "0.4.0" base_url = "floorplan" - min_version = "3.4.1" - + min_version = "4.0.2" + max_version = "4.0.99" config = FloorplanConfig diff --git a/netbox_floorplan/admin.py b/netbox_floorplan/admin.py index 88c45d7..e69de29 100644 --- a/netbox_floorplan/admin.py +++ b/netbox_floorplan/admin.py @@ -1,9 +0,0 @@ -from django.contrib import admin -from .models import Floorplan - - -@admin.register(Floorplan) -class FloorplanAdmin(admin.ModelAdmin): - list_display = ( - "pk", - ) diff --git a/netbox_floorplan/static/netbox_floorplan/floorplan/edit.js b/netbox_floorplan/static/netbox_floorplan/floorplan/edit.js index 01ede7f..8bb8de5 100644 --- a/netbox_floorplan/static/netbox_floorplan/floorplan/edit.js +++ b/netbox_floorplan/static/netbox_floorplan/floorplan/edit.js @@ -1,5 +1,6 @@ // start initial ----------------------------------------------------------------------------- ! + import { resize_canvas, export_svg, diff --git a/netbox_floorplan/templates/netbox_floorplan/floorplan_edit.html b/netbox_floorplan/templates/netbox_floorplan/floorplan_edit.html index 8e18926..ae6768c 100644 --- a/netbox_floorplan/templates/netbox_floorplan/floorplan_edit.html +++ b/netbox_floorplan/templates/netbox_floorplan/floorplan_edit.html @@ -1,8 +1,8 @@ -{% extends 'base/layout.html' %} +{% extends 'generic/_base.html' %} {% load static %} {% load form_helpers %} {% load helpers %} - +{% load django_htmx %} {% block head %} {{ block.super }} @@ -27,7 +27,7 @@ {% endblock tabs %} -{% block content-wrapper %} +{% block content %} {% load template_utils %} @@ -55,7 +55,7 @@
Controls
- Set Dimensions @@ -97,18 +97,18 @@
Controls
- Add + Add Wall - Add + Add Area - + Add label - Lock/Unlock Object + Lock/Unlock Object - Delete @@ -116,7 +116,7 @@
Controls
- + Set Color @@ -126,10 +126,10 @@
Controls
-
Forward - Backwards @@ -140,10 +140,10 @@
Controls
- + Reset Zoom - Center @@ -152,10 +152,10 @@
Controls
- + Save - + Export SVG @@ -219,5 +219,5 @@