Coverage for extras/constants.py: 100%
14 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from jinja2 import ChainableUndefined, DebugUndefined, StrictUndefined, Undefined
3from core.events import *
4from extras.choices import LogLevelChoices
6# Custom fields
7CUSTOMFIELD_EMPTY_VALUES = (None, '', [])
9# Timeout (in seconds) applied to the background jobs which provision and purge custom field data.
10# These jobs exist precisely because the work is too large for the request which triggered it, so
11# the default RQ timeout -- being of the same order as the request timeout being escaped -- would
12# reimpose the limit they were introduced to avoid. A timeout is recoverable, as each job commits
13# its batches independently and both are idempotent, but it leaves the field pending until the job
14# is run again. Three hours is well beyond what a batched update of any real table takes, while
15# still releasing a worker blocked on an unresponsive database.
16CUSTOMFIELD_JOB_TIMEOUT = 10800
18# ImageAttachment
19IMAGE_ATTACHMENT_IMAGE_FORMATS = {
20 'avif': 'image/avif',
21 'bmp': 'image/bmp',
22 'gif': 'image/gif',
23 'jpeg': 'image/jpeg',
24 'jpg': 'image/jpeg',
25 'png': 'image/png',
26 'webp': 'image/webp',
27}
29# Template Export
30DEFAULT_MIME_TYPE = 'text/plain; charset=utf-8'
32# Scripts
33# Prefix applied to dynamically-loaded script/report module names so that a script whose filename
34# matches a core app or package (e.g. "circuits.py") cannot shadow it in sys.modules.
35SCRIPT_MODULE_NAME_PREFIX = '_netbox_script_module_'
37# Webhooks
38HTTP_CONTENT_TYPE_JSON = 'application/json'
40WEBHOOK_EVENT_TYPES = {
41 # Map registered event types to public webhook "event" equivalents
42 OBJECT_CREATED: 'created',
43 OBJECT_UPDATED: 'updated',
44 OBJECT_DELETED: 'deleted',
45 JOB_STARTED: 'job_started',
46 JOB_COMPLETED: 'job_ended',
47 JOB_FAILED: 'job_ended',
48 JOB_ERRORED: 'job_ended',
49}
51# Allowed Jinja2 environment parameters and their permitted values.
52# Only keys listed here may appear in a template's environment_params.
53# None = any JSON-serializable value accepted (scalars, booleans, etc.)
54# dict = only dict keys accepted; dict values are the resolved Python objects
55#
56# Note: 'finalize' is intentionally absent. It is deprecated and handled as a
57# legacy carve-out in RenderTemplateMixin (blocked from new use, but existing
58# stored values continue to resolve via import_string at render time).
59JINJA_ENV_PARAMS_ALLOWED = {
60 # Boolean / scalar params (accept any JSON-serializable value)
61 'auto_reload': None,
62 'autoescape': None,
63 'cache_size': None,
64 'enable_async': None,
65 'keep_trailing_newline': None,
66 'lstrip_blocks': None,
67 'optimized': None,
68 'trim_blocks': None,
69 # String params (template syntax delimiters)
70 'block_start_string': None,
71 'block_end_string': None,
72 'comment_start_string': None,
73 'comment_end_string': None,
74 'line_comment_prefix': None,
75 'line_statement_prefix': None,
76 'newline_sequence': None,
77 'variable_start_string': None,
78 'variable_end_string': None,
79 # Mapped params (value must be a key in the dict; resolved to the dict value)
80 'undefined': {
81 'jinja2.ChainableUndefined': ChainableUndefined,
82 'jinja2.DebugUndefined': DebugUndefined,
83 'jinja2.StrictUndefined': StrictUndefined,
84 'jinja2.Undefined': Undefined,
85 },
86 # Excluded (dangerous — accept callables or trigger imports):
87 # 'bytecode_cache' — accepts arbitrary object
88 # 'extensions' — Jinja2 internally calls import_string() on string entries
89 # 'finalize' — deprecated; legacy carve-out in RenderTemplateMixin
90 # 'loader' — accepts arbitrary object
91}
93# Dashboard
94DEFAULT_DASHBOARD = [
95 {
96 'widget': 'extras.BookmarksWidget',
97 'width': 4,
98 'height': 5,
99 'title': 'Bookmarks',
100 'color': 'orange',
101 },
102 {
103 'widget': 'extras.ObjectCountsWidget',
104 'width': 4,
105 'height': 2,
106 'title': 'Organization',
107 'config': {
108 'models': [
109 'dcim.site',
110 'tenancy.tenant',
111 'tenancy.contact',
112 ]
113 }
114 },
115 {
116 'widget': 'extras.NoteWidget',
117 'width': 4,
118 'height': 2,
119 'title': 'Welcome!',
120 'color': 'green',
121 'config': {
122 'content': (
123 'This is your personal dashboard. Feel free to customize it by rearranging, resizing, or removing '
124 'widgets. You can also add new widgets using the "add widget" button below. Any changes affect only '
125 '_your_ dashboard, so feel free to experiment!'
126 )
127 }
128 },
129 {
130 'widget': 'extras.ObjectCountsWidget',
131 'width': 4,
132 'height': 3,
133 'title': 'IPAM',
134 'config': {
135 'models': [
136 'ipam.vrf',
137 'ipam.aggregate',
138 'ipam.prefix',
139 'ipam.iprange',
140 'ipam.ipaddress',
141 'ipam.vlan',
142 ]
143 }
144 },
145 {
146 'widget': 'extras.RSSFeedWidget',
147 'width': 4,
148 'height': 4,
149 'title': 'NetBox News',
150 'config': {
151 'feed_url': 'https://api.netbox.oss.netboxlabs.com/v1/newsfeed/',
152 'max_entries': 10,
153 'cache_timeout': 14400,
154 'requires_internet': True,
155 }
156 },
157 {
158 'widget': 'extras.ObjectCountsWidget',
159 'width': 4,
160 'height': 3,
161 'title': 'Circuits',
162 'config': {
163 'models': [
164 'circuits.provider',
165 'circuits.circuit',
166 'circuits.providernetwork',
167 'circuits.provideraccount',
168 ]
169 }
170 },
171 {
172 'widget': 'extras.ObjectCountsWidget',
173 'width': 4,
174 'height': 3,
175 'title': 'DCIM',
176 'config': {
177 'models': [
178 'dcim.site',
179 'dcim.rack',
180 'dcim.devicetype',
181 'dcim.device',
182 'dcim.cable',
183 ],
184 }
185 },
186 {
187 'widget': 'extras.ObjectCountsWidget',
188 'width': 4,
189 'height': 2,
190 'title': 'Virtualization',
191 'config': {
192 'models': [
193 'virtualization.cluster',
194 'virtualization.virtualmachine',
195 ]
196 }
197 },
198 {
199 'widget': 'extras.ObjectListWidget',
200 'width': 12,
201 'height': 5,
202 'title': 'Change Log',
203 'color': 'blue',
204 'config': {
205 'model': 'core.objectchange',
206 'page_size': 25,
207 }
208 },
209]
211LOG_LEVEL_RANK = {
212 LogLevelChoices.LOG_DEBUG: 0,
213 LogLevelChoices.LOG_INFO: 1,
214 LogLevelChoices.LOG_SUCCESS: 2,
215 LogLevelChoices.LOG_WARNING: 3,
216 LogLevelChoices.LOG_FAILURE: 4,
217}
219# Config context cache: fields whose modification on an object requires re-rendering its config
220# context cache, keyed by model label.
221CC_FIELDS_BY_MODEL = {
222 'dcim.device': (
223 'site_id', 'location_id', 'device_type_id', 'role_id', 'tenant_id', 'platform_id',
224 'cluster_id', 'local_context_data',
225 ),
226 'virtualization.virtualmachine': (
227 'site_id', 'cluster_id', 'tenant_id', 'platform_id', 'role_id', 'local_context_data',
228 ),
229}