From 26399e224dddb99485dcc85c3c7ff3eb6372ddc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ma=CC=88der?= Date: Fri, 7 Oct 2022 22:33:41 +0200 Subject: [PATCH] Make dynamic configuration parameters actually work --- configuration/configuration.py | 88 +++++++++++++++++++++++----------- env/netbox.env | 4 -- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/configuration/configuration.py b/configuration/configuration.py index 8507723..5518af6 100644 --- a/configuration/configuration.py +++ b/configuration/configuration.py @@ -7,7 +7,8 @@ import re from os import environ from os.path import abspath, dirname, join -from typing import Any, Callable +from termios import VREPRINT +from typing import Any, Callable, Tuple # For reference see https://docs.netbox.dev/en/stable/configuration/ # Based on https://github.com/netbox-community/netbox/blob/develop/netbox/netbox/configuration_example.py @@ -117,29 +118,33 @@ SECRET_KEY = _read_secret('secret_key', environ.get('SECRET_KEY', '')) # # ['John Doe', 'jdoe@example.com'], # ] -# URL schemes that are allowed within links in NetBox -_DEFAULT_ALLOWED_URL_SCHEMES = ( - 'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp', -) -ALLOWED_URL_SCHEMES = _environ_get_and_map('ALLOWED_URL_SCHEMES', ' '.join(_DEFAULT_ALLOWED_URL_SCHEMES), _SPLIT_ON_SPACE) +_ALLOWED_URL_SCHEMES = _environ_get_and_map('ALLOWED_URL_SCHEMES', None, _SPLIT_ON_SPACE) +if _ALLOWED_URL_SCHEMES: + ALLOWED_URL_SCHEMES = _ALLOWED_URL_SCHEMES # 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 = environ.get('BANNER_TOP', None) -BANNER_BOTTOM = environ.get('BANNER_BOTTOM', None) +if 'BANNER_TOP' in environ: + BANNER_TOP = environ.get('BANNER_TOP', None) +if 'BANNER_BOTTOM' in environ: + BANNER_BOTTOM = environ.get('BANNER_BOTTOM', None) # Text to include on the login page above the login form. HTML is allowed. -BANNER_LOGIN = environ.get('BANNER_LOGIN', None) +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) -CHANGELOG_RETENTION = _environ_get_and_map('CHANGELOG_RETENTION', None, _AS_INT) +_CHANGELOG_RETENTION = _environ_get_and_map('CHANGELOG_RETENTION', None, _AS_INT) +if _CHANGELOG_RETENTION: + CHANGELOG_RETENTION = _CHANGELOG_RETENTION # Maximum number of days to retain job results (scripts and reports). Set to 0 to retain job results in the database indefinitely. (Default: 90) -JOBRESULT_RETENTION = _environ_get_and_map('CHANGELOG_RETENTION', None, _AS_INT) +if 'JOBRESULT_RETENTION' in environ: + JOBRESULT_RETENTION = _environ_get_and_map('JOBRESULT_RETENTION', None, _AS_INT) # 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 @@ -156,7 +161,7 @@ DEBUG = _environ_get_and_map('DEBUG', 'False', _EQUALS_TRUE) # This parameter serves as a safeguard to prevent some potentially dangerous behavior, # such as generating new database schema migrations. # Set this to True only if you are actively developing the NetBox code base. -DEVELOPER = _environ_get_and_map('DEBUG', 'False', _EQUALS_TRUE) +DEVELOPER = _environ_get_and_map('DEVELOPER', 'False', _EQUALS_TRUE) # Email settings EMAIL = { @@ -174,7 +179,9 @@ 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 = _environ_get_and_map('ENFORCE_GLOBAL_UNIQUE', None, _EQUALS_TRUE) +_ENFORCE_GLOBAL_UNIQUE = _environ_get_and_map('ENFORCE_GLOBAL_UNIQUE', None, _EQUALS_TRUE) +if _ENFORCE_GLOBAL_UNIQUE: + ENFORCE_GLOBAL_UNIQUE = _ENFORCE_GLOBAL_UNIQUE # 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 `.`. Add '*' to this list to exempt all models. @@ -191,7 +198,9 @@ EXEMPT_VIEW_PERMISSIONS = _environ_get_and_map('EXEMPT_VIEW_PERMISSIONS', '', _S INTERNAL_IPS = _environ_get_and_map('INTERNAL_IPS', '127.0.0.1 ::1', _SPLIT_ON_SPACE) # Enable GraphQL API. -GRAPHQL_ENABLED = _environ_get_and_map('GRAPHQL_ENABLED', None, _EQUALS_TRUE) +_GRAPHQL_ENABLED = _environ_get_and_map('GRAPHQL_ENABLED', None, _EQUALS_TRUE) +if _GRAPHQL_ENABLED: + GRAPHQL_ENABLED = _GRAPHQL_ENABLED # # Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs: # # https://docs.djangoproject.com/en/stable/topics/logging/ @@ -210,15 +219,20 @@ LOGIN_REQUIRED = _environ_get_and_map('LOGIN_REQUIRED', 'False', _EQUALS_TRUE) LOGIN_TIMEOUT = _environ_get_and_map('LOGIN_TIMEOUT', 1209600, _AS_INT) # Setting this to True will display a "maintenance mode" banner at the top of every page. -MAINTENANCE_MODE = _environ_get_and_map('MAINTENANCE_MODE', None, _EQUALS_TRUE) +_MAINTENANCE_MODE = _environ_get_and_map('MAINTENANCE_MODE', None, _EQUALS_TRUE) +if _MAINTENANCE_MODE: + MAINTENANCE_MODE = _MAINTENANCE_MODE # Maps provider -MAPS_URL = environ.get('MAPS_URL', None) +if 'MAPS_URL' in environ: + MAPS_URL = environ.get('MAPS_URL', None) # 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 = _environ_get_and_map('MAX_PAGE_SIZE', None, _AS_INT) +_MAX_PAGE_SIZE = _environ_get_and_map('MAX_PAGE_SIZE', None, _AS_INT) +if _MAX_PAGE_SIZE: + MAX_PAGE_SIZE = _MAX_PAGE_SIZE # 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. @@ -228,18 +242,24 @@ MEDIA_ROOT = environ.get('MEDIA_ROOT', join(_BASE_DIR, 'media')) METRICS_ENABLED = _environ_get_and_map('METRICS_ENABLED', 'False', _EQUALS_TRUE) # Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM. -NAPALM_USERNAME = environ.get('NAPALM_USERNAME', None) -NAPALM_PASSWORD = _read_secret('napalm_password', environ.get('NAPALM_PASSWORD', None)) +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) -NAPALM_TIMEOUT = _environ_get_and_map('NAPALM_TIMEOUT', None, _AS_INT) +_NAPALM_TIMEOUT = _environ_get_and_map('NAPALM_TIMEOUT', None, _AS_INT) +if _NAPALM_TIMEOUT: + NAPALM_TIMEOUT = _NAPALM_TIMEOUT # # 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) -PAGINATE_COUNT = _environ_get_and_map('PAGINATE_COUNT', None, _AS_INT) +_PAGINATE_COUNT = _environ_get_and_map('PAGINATE_COUNT', None, _AS_INT) +if _PAGINATE_COUNT: + PAGINATE_COUNT = _PAGINATE_COUNT # # Enable installed plugins. Add the name of each plugin to the list. # PLUGINS = [] @@ -251,20 +271,32 @@ PAGINATE_COUNT = _environ_get_and_map('PAGINATE_COUNT', None, _AS_INT) # 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 = _environ_get_and_map('PREFER_IPV4', None, _EQUALS_TRUE) +_PREFER_IPV4 = _environ_get_and_map('PREFER_IPV4', None, _EQUALS_TRUE) +if _PREFER_IPV4: + PREFER_IPV = _PREFER_IPV4 # The default value for the amperage field when creating new power feeds. -POWERFEED_DEFAULT_AMPERAGE = _environ_get_and_map('POWERFEED_DEFAULT_AMPERAGE', None, _AS_INT) +_POWERFEED_DEFAULT_AMPERAGE = _environ_get_and_map('POWERFEED_DEFAULT_AMPERAGE', None, _AS_INT) +if _POWERFEED_DEFAULT_AMPERAGE: + POWERFEED_DEFAULT_AMPERAGE = _POWERFEED_DEFAULT_AMPERAGE # The default value (percentage) for the max_utilization field when creating new power feeds. -POWERFEED_DEFAULT_MAX_UTILIZATION = _environ_get_and_map('POWERFEED_DEFAULT_MAX_UTILIZATION', None, _AS_INT) +_POWERFEED_DEFAULT_MAX_UTILIZATION = _environ_get_and_map('POWERFEED_DEFAULT_MAX_UTILIZATION', None, _AS_INT) +if _POWERFEED_DEFAULT_MAX_UTILIZATION: + POWERFEED_DEFAULT_MAX_UTILIZATION = _POWERFEED_DEFAULT_MAX_UTILIZATION # The default value for the voltage field when creating new power feeds. -POWERFEED_DEFAULT_VOLTAGE = _environ_get_and_map('POWERFEED_DEFAULT_VOLTAGE', None, _AS_INT) +_POWERFEED_DEFAULT_VOLTAGE = _environ_get_and_map('POWERFEED_DEFAULT_VOLTAGE', None, _AS_INT) +if _POWERFEED_DEFAULT_VOLTAGE: + POWERFEED_DEFAULT_VOLTAGE = _POWERFEED_DEFAULT_VOLTAGE # Rack elevation size defaults, in pixels. For best results, the ratio of width to height should be roughly 10:1. -RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = _environ_get_and_map('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', None, _AS_INT) -RACK_ELEVATION_DEFAULT_UNIT_WIDTH = _environ_get_and_map('RACK_ELEVATION_DEFAULT_UNIT_WIDTH', None, _AS_INT) +_RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = _environ_get_and_map('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', None, _AS_INT) +if _RACK_ELEVATION_DEFAULT_UNIT_HEIGHT: + RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = _RACK_ELEVATION_DEFAULT_UNIT_HEIGHT +_RACK_ELEVATION_DEFAULT_UNIT_WIDTH = _environ_get_and_map('RACK_ELEVATION_DEFAULT_UNIT_WIDTH', None, _AS_INT) +if _RACK_ELEVATION_DEFAULT_UNIT_WIDTH: + RACK_ELEVATION_DEFAULT_UNIT_WIDTH = _RACK_ELEVATION_DEFAULT_UNIT_WIDTH # Remote authentication support REMOTE_AUTH_ENABLED = _environ_get_and_map('REMOTE_AUTH_ENABLED', 'False', _EQUALS_TRUE) @@ -304,7 +336,7 @@ SESSION_COOKIE_NAME = environ.get('SESSION_COOKIE_NAME', 'sessionid') # 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 # database access.) Note that the user as which NetBox runs must have read and write permissions to this path. -SESSION_FILE_PATH = environ.get('SESSIONS_ROOT', None) +SESSION_FILE_PATH = environ.get('SESSION_FILE_PATH', environ.get('SESSIONS_ROOT', None)) # Time zone (default: UTC) TIME_ZONE = environ.get('TIME_ZONE', 'UTC') diff --git a/env/netbox.env b/env/netbox.env index b2f647e..a4a9d4a 100644 --- a/env/netbox.env +++ b/env/netbox.env @@ -16,12 +16,8 @@ EMAIL_USE_SSL=false EMAIL_USE_TLS=false GRAPHQL_ENABLED=true HOUSEKEEPING_INTERVAL=86400 -MAX_PAGE_SIZE=1000 MEDIA_ROOT=/opt/netbox/netbox/media METRICS_ENABLED=false -NAPALM_PASSWORD= -NAPALM_TIMEOUT=10 -NAPALM_USERNAME= REDIS_CACHE_DATABASE=1 REDIS_CACHE_HOST=redis-cache REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY=false