mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Introduce ConfigItem; add rack elevation parameters
This commit is contained in:
parent
82243732a1
commit
7c0f32e8ee
@ -13,6 +13,7 @@ from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField
|
||||
from netbox.api.serializers import (
|
||||
NestedGroupModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
|
||||
)
|
||||
from netbox.config import ConfigItem
|
||||
from tenancy.api.nested_serializers import NestedTenantSerializer
|
||||
from users.api.nested_serializers import NestedUserSerializer
|
||||
from utilities.api import get_serializer_for_model
|
||||
@ -229,10 +230,10 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
|
||||
default=RackElevationDetailRenderChoices.RENDER_JSON
|
||||
)
|
||||
unit_width = serializers.IntegerField(
|
||||
default=settings.RACK_ELEVATION_DEFAULT_UNIT_WIDTH
|
||||
default=ConfigItem('RACK_ELEVATION_DEFAULT_UNIT_WIDTH')
|
||||
)
|
||||
unit_height = serializers.IntegerField(
|
||||
default=settings.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT
|
||||
default=ConfigItem('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT')
|
||||
)
|
||||
legend_width = serializers.IntegerField(
|
||||
default=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT
|
||||
|
@ -1,7 +1,6 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
import yaml
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
@ -15,7 +14,7 @@ from dcim.constants import *
|
||||
from extras.models import ConfigContextModel
|
||||
from extras.querysets import ConfigContextModelQuerySet
|
||||
from extras.utils import extras_features
|
||||
from netbox.config import ConfigResolver
|
||||
from netbox.config import ConfigItem
|
||||
from netbox.models import OrganizationalModel, PrimaryModel
|
||||
from utilities.choices import ColorChoices
|
||||
from utilities.fields import ColorField, NaturalOrderingField
|
||||
@ -816,8 +815,7 @@ class Device(PrimaryModel, ConfigContextModel):
|
||||
|
||||
@property
|
||||
def primary_ip(self):
|
||||
config = ConfigResolver()
|
||||
if config.PREFER_IPV4 and self.primary_ip4:
|
||||
if ConfigItem('PREFER_IPV4')() and self.primary_ip4:
|
||||
return self.primary_ip4
|
||||
elif self.primary_ip6:
|
||||
return self.primary_ip6
|
||||
|
@ -1,6 +1,5 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
@ -15,6 +14,7 @@ from dcim.choices import *
|
||||
from dcim.constants import *
|
||||
from dcim.svg import RackElevationSVG
|
||||
from extras.utils import extras_features
|
||||
from netbox.config import Config
|
||||
from netbox.models import OrganizationalModel, PrimaryModel
|
||||
from utilities.choices import ColorChoices
|
||||
from utilities.fields import ColorField, NaturalOrderingField
|
||||
@ -373,8 +373,8 @@ class Rack(PrimaryModel):
|
||||
self,
|
||||
face=DeviceFaceChoices.FACE_FRONT,
|
||||
user=None,
|
||||
unit_width=settings.RACK_ELEVATION_DEFAULT_UNIT_WIDTH,
|
||||
unit_height=settings.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT,
|
||||
unit_width=None,
|
||||
unit_height=None,
|
||||
legend_width=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT,
|
||||
include_images=True,
|
||||
base_url=None
|
||||
@ -393,6 +393,10 @@ class Rack(PrimaryModel):
|
||||
:param base_url: Base URL for links and images. If none, URLs will be relative.
|
||||
"""
|
||||
elevation = RackElevationSVG(self, user=user, include_images=include_images, base_url=base_url)
|
||||
if unit_width is None or unit_height is None:
|
||||
config = Config()
|
||||
unit_width = unit_width or config.RACK_ELEVATION_DEFAULT_UNIT_WIDTH
|
||||
unit_height = unit_height or config.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT
|
||||
|
||||
return elevation.render(face, unit_width, unit_height, legend_width)
|
||||
|
||||
|
@ -10,9 +10,9 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
|
||||
# ('Authentication', {
|
||||
# 'fields': ('LOGIN_REQUIRED', 'LOGIN_PERSISTENCE', 'LOGIN_TIMEOUT'),
|
||||
# }),
|
||||
# ('Rack Elevations', {
|
||||
# 'fields': ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH'),
|
||||
# }),
|
||||
('Rack Elevations', {
|
||||
'fields': ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH'),
|
||||
}),
|
||||
('IPAM', {
|
||||
'fields': ('ENFORCE_GLOBAL_UNIQUE', 'PREFER_IPV4'),
|
||||
}),
|
||||
|
@ -1,10 +1,9 @@
|
||||
import netaddr
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.db.models import F, Q
|
||||
from django.db.models import F
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
@ -17,7 +16,7 @@ from ipam.fields import IPNetworkField, IPAddressField
|
||||
from ipam.managers import IPAddressManager
|
||||
from ipam.querysets import PrefixQuerySet
|
||||
from ipam.validators import DNSValidator
|
||||
from netbox.config import ConfigResolver
|
||||
from netbox.config import Config
|
||||
from utilities.querysets import RestrictedQuerySet
|
||||
from virtualization.models import VirtualMachine
|
||||
|
||||
@ -317,8 +316,7 @@ class Prefix(PrimaryModel):
|
||||
})
|
||||
|
||||
# Enforce unique IP space (if applicable)
|
||||
config = ConfigResolver()
|
||||
if (self.vrf is None and config.ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique):
|
||||
if (self.vrf is None and Config().ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique):
|
||||
duplicate_prefixes = self.get_duplicates()
|
||||
if duplicate_prefixes:
|
||||
raise ValidationError({
|
||||
@ -813,8 +811,7 @@ class IPAddress(PrimaryModel):
|
||||
})
|
||||
|
||||
# Enforce unique IP space (if applicable)
|
||||
config = ConfigResolver()
|
||||
if (self.vrf is None and config.ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique):
|
||||
if (self.vrf is None and Config().ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique):
|
||||
duplicate_ips = self.get_duplicates()
|
||||
if duplicate_ips and (
|
||||
self.role not in IPADDRESS_ROLES_NONUNIQUE or
|
||||
|
@ -4,18 +4,20 @@ from django.core.cache import cache
|
||||
from .parameters import PARAMS
|
||||
|
||||
__all__ = (
|
||||
'ConfigResolver',
|
||||
'Config',
|
||||
'ConfigItem',
|
||||
'PARAMS',
|
||||
)
|
||||
|
||||
|
||||
class ConfigResolver:
|
||||
class Config:
|
||||
"""
|
||||
Active NetBox configuration.
|
||||
Fetch and store in memory the current NetBox configuration. This class must be instantiated prior to access, and
|
||||
must be re-instantiated each time it's necessary to check for updates to the cached config.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.config = cache.get('config')
|
||||
self.version = self.config.get('config_version')
|
||||
self.version = cache.get('config_version')
|
||||
self.defaults = {param.name: param.default for param in PARAMS}
|
||||
|
||||
def __getattr__(self, item):
|
||||
@ -33,3 +35,16 @@ class ConfigResolver:
|
||||
return self.defaults[item]
|
||||
|
||||
raise AttributeError(f"Invalid configuration parameter: {item}")
|
||||
|
||||
|
||||
class ConfigItem:
|
||||
"""
|
||||
A callable to retrieve a configuration parameter from the cache. This can serve as a placeholder to defer
|
||||
referencing a configuration parameter.
|
||||
"""
|
||||
def __init__(self, item):
|
||||
self.item = item
|
||||
|
||||
def __call__(self):
|
||||
config = Config()
|
||||
return getattr(config, self.item)
|
||||
|
@ -52,4 +52,20 @@ PARAMS = (
|
||||
field=OptionalBooleanField
|
||||
),
|
||||
|
||||
# Racks
|
||||
ConfigParam(
|
||||
name='RACK_ELEVATION_DEFAULT_UNIT_HEIGHT',
|
||||
label='Rack Unit Height',
|
||||
default=22,
|
||||
description="Default unit height for rendered rack elevations",
|
||||
field=forms.IntegerField
|
||||
),
|
||||
ConfigParam(
|
||||
name='RACK_ELEVATION_DEFAULT_UNIT_WIDTH',
|
||||
label='Rack Unit Width',
|
||||
default=220,
|
||||
description="Default unit width for rendered rack elevations",
|
||||
field=forms.IntegerField
|
||||
),
|
||||
|
||||
)
|
||||
|
@ -77,14 +77,6 @@ ALLOWED_URL_SCHEMES = (
|
||||
'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
|
||||
)
|
||||
|
||||
# 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 = ''
|
||||
BANNER_BOTTOM = ''
|
||||
|
||||
# Text to include on the login page above the login form. HTML is allowed.
|
||||
BANNER_LOGIN = ''
|
||||
|
||||
# Base URL path if accessing NetBox within a directory. For example, if installed at https://example.com/netbox/, set:
|
||||
# BASE_PATH = 'netbox/'
|
||||
BASE_PATH = ''
|
||||
@ -134,10 +126,6 @@ EMAIL = {
|
||||
'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
|
||||
|
||||
# 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.
|
||||
EXEMPT_VIEW_PERMISSIONS = [
|
||||
@ -229,14 +217,6 @@ PLUGINS = []
|
||||
# }
|
||||
# }
|
||||
|
||||
# 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 = False
|
||||
|
||||
# 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 = 22
|
||||
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = 220
|
||||
|
||||
# Remote authentication support
|
||||
REMOTE_AUTH_ENABLED = False
|
||||
REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
|
||||
|
@ -1,7 +1,7 @@
|
||||
from django.conf import settings as django_settings
|
||||
|
||||
from extras.registry import registry
|
||||
from netbox.config import ConfigResolver
|
||||
from netbox.config import Config
|
||||
|
||||
|
||||
def settings_and_registry(request):
|
||||
@ -10,7 +10,7 @@ def settings_and_registry(request):
|
||||
"""
|
||||
return {
|
||||
'settings': django_settings,
|
||||
'config': ConfigResolver(),
|
||||
'config': Config(),
|
||||
'registry': registry,
|
||||
'preferences': request.user.config if request.user.is_authenticated else {},
|
||||
}
|
||||
|
@ -140,8 +140,6 @@ NAPALM_PASSWORD = getattr(configuration, 'NAPALM_PASSWORD', '')
|
||||
NAPALM_TIMEOUT = getattr(configuration, 'NAPALM_TIMEOUT', 30)
|
||||
NAPALM_USERNAME = getattr(configuration, 'NAPALM_USERNAME', '')
|
||||
PAGINATE_COUNT = getattr(configuration, 'PAGINATE_COUNT', 50)
|
||||
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = getattr(configuration, 'RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 22)
|
||||
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = getattr(configuration, 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH', 220)
|
||||
RELEASE_CHECK_URL = getattr(configuration, 'RELEASE_CHECK_URL', None)
|
||||
|
||||
# Validate update repo URL and timeout
|
||||
|
@ -8,7 +8,7 @@ from dcim.models import BaseInterface, Device
|
||||
from extras.models import ConfigContextModel
|
||||
from extras.querysets import ConfigContextModelQuerySet
|
||||
from extras.utils import extras_features
|
||||
from netbox.config import ConfigResolver
|
||||
from netbox.config import Config
|
||||
from netbox.models import OrganizationalModel, PrimaryModel
|
||||
from utilities.fields import NaturalOrderingField
|
||||
from utilities.ordering import naturalize_interface
|
||||
@ -340,8 +340,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
|
||||
|
||||
@property
|
||||
def primary_ip(self):
|
||||
config = ConfigResolver()
|
||||
if config.PREFER_IPV4 and self.primary_ip4:
|
||||
if Config().PREFER_IPV4 and self.primary_ip4:
|
||||
return self.primary_ip4
|
||||
elif self.primary_ip6:
|
||||
return self.primary_ip6
|
||||
|
Loading…
Reference in New Issue
Block a user