Coverage for extras/choices.py: 100%
110 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
1import logging
3from django.utils.translation import gettext_lazy as _
5from netbox.choices import ButtonColorChoices
6from utilities.choices import Choice, ChoiceSet
8#
9# CustomFields
10#
13class CustomFieldTypeChoices(ChoiceSet):
15 TYPE_TEXT = 'text'
16 TYPE_LONGTEXT = 'longtext'
17 TYPE_INTEGER = 'integer'
18 TYPE_DECIMAL = 'decimal'
19 TYPE_BOOLEAN = 'boolean'
20 TYPE_DATE = 'date'
21 TYPE_DATETIME = 'datetime'
22 TYPE_URL = 'url'
23 TYPE_JSON = 'json'
24 TYPE_SELECT = 'select'
25 TYPE_MULTISELECT = 'multiselect'
26 TYPE_OBJECT = 'object'
27 TYPE_MULTIOBJECT = 'multiobject'
29 CHOICES = (
30 Choice(TYPE_TEXT, _('Text'), description=_('A single line of text')),
31 Choice(TYPE_LONGTEXT, _('Text (long)'), description=_('Multi-line text with Markdown support')),
32 Choice(TYPE_INTEGER, _('Integer'), description=_('A whole number (positive or negative)')),
33 Choice(TYPE_DECIMAL, _('Decimal'), description=_('A fixed-precision decimal number')),
34 Choice(TYPE_BOOLEAN, _('Boolean'), description=_('A true or false value')),
35 Choice(TYPE_DATE, _('Date'), description=_('A calendar date')),
36 Choice(TYPE_DATETIME, _('Date & time'), description=_('A calendar date and time')),
37 Choice(TYPE_URL, _('URL'), description=_('A hyperlink to an external resource')),
38 Choice(TYPE_JSON, _('JSON'), description=_('Arbitrary data encoded as JSON')),
39 Choice(TYPE_SELECT, _('Selection'), description=_('A single value chosen from a predefined list')),
40 Choice(
41 TYPE_MULTISELECT,
42 _('Multiple selection'),
43 description=_('One or more values chosen from a predefined list')
44 ),
45 Choice(TYPE_OBJECT, _('Object'), description=_('A reference to a single NetBox object')),
46 Choice(TYPE_MULTIOBJECT, _('Multiple objects'), description=_('References to one or more NetBox objects')),
47 )
50class CustomFieldStatusChoices(ChoiceSet):
51 """
52 The lifecycle state of a CustomField.
54 A field participates in object data only while active. The remaining states indicate that a bulk
55 update of its stored data is pending or in progress, during which the field is not live but its
56 row continues to reserve the field's name.
57 """
58 STATUS_ACTIVE = 'active'
59 STATUS_PROVISIONING = 'provisioning'
60 STATUS_DELETING = 'deleting'
62 CHOICES = (
63 (STATUS_ACTIVE, _('Active'), 'green'),
64 (STATUS_PROVISIONING, _('Provisioning'), 'cyan'),
65 (STATUS_DELETING, _('Deleting'), 'red'),
66 )
68 # The statuses in which the field's stored object data is its own: an active field's data is
69 # live, and a provisioning field's is being written by the job which will bring it live. Data
70 # held for a field in one of these statuses is left alone when an object is saved, and its
71 # default is populated on objects which lack it. A deleting field's data is on its way out, and
72 # so is excluded (see CustomFieldsMixin.clean() and get_defaults_for_model()).
73 DATA_STATUSES = (STATUS_ACTIVE, STATUS_PROVISIONING)
76class CustomFieldFilterLogicChoices(ChoiceSet):
78 FILTER_DISABLED = 'disabled'
79 FILTER_LOOSE = 'loose'
80 FILTER_EXACT = 'exact'
82 CHOICES = (
83 Choice(FILTER_DISABLED, _('Disabled'), description=_('The field cannot be used for filtering')),
84 Choice(FILTER_LOOSE, _('Loose'), description=_('Match on a partial value (case-insensitive substring)')),
85 Choice(FILTER_EXACT, _('Exact'), description=_('Match on the exact value')),
86 )
89class CustomFieldUIVisibleChoices(ChoiceSet):
91 ALWAYS = 'always'
92 IF_SET = 'if-set'
93 HIDDEN = 'hidden'
95 CHOICES = (
96 Choice(ALWAYS, _('Always'), color='green', description=_('Always display the field')),
97 Choice(IF_SET, _('If set'), color='yellow', description=_('Display the field only if it has a value')),
98 Choice(HIDDEN, _('Hidden'), color='gray', description=_('Never display the field')),
99 )
102class CustomFieldUIEditableChoices(ChoiceSet):
104 YES = 'yes'
105 NO = 'no'
106 HIDDEN = 'hidden'
108 CHOICES = (
109 Choice(YES, _('Yes'), color='green', description=_('The field value can be edited by users')),
110 Choice(NO, _('No'), color='red', description=_('The field is displayed but cannot be edited')),
111 Choice(HIDDEN, _('Hidden'), color='gray', description=_('The field is neither displayed nor editable')),
112 )
115class CustomFieldChoiceSetBaseChoices(ChoiceSet):
117 IATA = 'IATA'
118 ISO_3166 = 'ISO_3166'
119 UN_LOCODE = 'UN_LOCODE'
121 CHOICES = (
122 Choice(IATA, 'IATA (Airport codes)'),
123 Choice(ISO_3166, 'ISO 3166 (Country codes)'),
124 Choice(UN_LOCODE, 'UN/LOCODE (Location codes)'),
125 )
128class CustomFieldChoiceColorChoices(ChoiceSet):
130 BLUE = 'blue'
131 INDIGO = 'indigo'
132 PURPLE = 'purple'
133 PINK = 'pink'
134 RED = 'red'
135 ORANGE = 'orange'
136 YELLOW = 'yellow'
137 GREEN = 'green'
138 TEAL = 'teal'
139 CYAN = 'cyan'
140 GRAY = 'gray'
141 BLACK = 'black'
142 WHITE = 'white'
144 CHOICES = (
145 Choice(BLUE, _('Blue'), color=BLUE),
146 Choice(INDIGO, _('Indigo'), color=INDIGO),
147 Choice(PURPLE, _('Purple'), color=PURPLE),
148 Choice(PINK, _('Pink'), color=PINK),
149 Choice(RED, _('Red'), color=RED),
150 Choice(ORANGE, _('Orange'), color=ORANGE),
151 Choice(YELLOW, _('Yellow'), color=YELLOW),
152 Choice(GREEN, _('Green'), color=GREEN),
153 Choice(TEAL, _('Teal'), color=TEAL),
154 Choice(CYAN, _('Cyan'), color=CYAN),
155 Choice(GRAY, _('Gray'), color=GRAY),
156 Choice(BLACK, _('Black'), color=BLACK),
157 Choice(WHITE, _('White'), color=WHITE),
158 )
161#
162# CustomLinks
163#
165class CustomLinkButtonClassChoices(ButtonColorChoices):
167 LINK = 'ghost-dark'
169 CHOICES = (
170 *ButtonColorChoices.CHOICES,
171 Choice(LINK, _('Link'), description=_('Render the button as a borderless text link')),
172 )
175#
176# Bookmarks
177#
179class BookmarkOrderingChoices(ChoiceSet):
181 ORDERING_NEWEST = '-created'
182 ORDERING_OLDEST = 'created'
183 ORDERING_ALPHABETICAL_AZ = 'name'
184 ORDERING_ALPHABETICAL_ZA = '-name'
186 CHOICES = (
187 Choice(ORDERING_NEWEST, _('Newest')),
188 Choice(ORDERING_OLDEST, _('Oldest')),
189 Choice(ORDERING_ALPHABETICAL_AZ, _('Alphabetical (A-Z)')),
190 Choice(ORDERING_ALPHABETICAL_ZA, _('Alphabetical (Z-A)')),
191 )
194#
195# Journal entries
196#
198class JournalEntryKindChoices(ChoiceSet):
199 key = 'JournalEntry.kind'
201 KIND_INFO = 'info'
202 KIND_SUCCESS = 'success'
203 KIND_WARNING = 'warning'
204 KIND_DANGER = 'danger'
206 CHOICES = [
207 Choice(KIND_INFO, _('Info'), color='cyan', description=_('An informational entry')),
208 Choice(KIND_SUCCESS, _('Success'), color='green', description=_('A record of a successful outcome')),
209 Choice(KIND_WARNING, _('Warning'), color='yellow', description=_('A cautionary note requiring attention')),
210 Choice(KIND_DANGER, _('Danger'), color='red', description=_('A record of a critical issue or failure')),
211 ]
214#
215# Reports and Scripts
216#
218class LogLevelChoices(ChoiceSet):
220 LOG_DEBUG = 'debug'
221 LOG_INFO = 'info'
222 LOG_SUCCESS = 'success'
223 LOG_WARNING = 'warning'
224 LOG_FAILURE = 'failure'
226 CHOICES = (
227 Choice(LOG_DEBUG, _('Debug'), color='teal'),
228 Choice(LOG_INFO, _('Info'), color='cyan'),
229 Choice(LOG_SUCCESS, _('Success'), color='green'),
230 Choice(LOG_WARNING, _('Warning'), color='yellow'),
231 Choice(LOG_FAILURE, _('Failure'), color='red'),
233 )
235 SYSTEM_LEVELS = {
236 LOG_DEBUG: logging.DEBUG,
237 LOG_INFO: logging.INFO,
238 LOG_SUCCESS: logging.INFO,
239 LOG_WARNING: logging.WARNING,
240 LOG_FAILURE: logging.ERROR,
241 }
244#
245# Webhooks
246#
248class WebhookHttpMethodChoices(ChoiceSet):
250 METHOD_GET = 'GET'
251 METHOD_POST = 'POST'
252 METHOD_PUT = 'PUT'
253 METHOD_PATCH = 'PATCH'
254 METHOD_DELETE = 'DELETE'
256 CHOICES = (
257 Choice(METHOD_GET, 'GET'),
258 Choice(METHOD_POST, 'POST'),
259 Choice(METHOD_PUT, 'PUT'),
260 Choice(METHOD_PATCH, 'PATCH'),
261 Choice(METHOD_DELETE, 'DELETE'),
262 )
265#
266# Dashboard widgets
267#
269class DashboardWidgetColorChoices(ChoiceSet):
270 BLUE = 'blue'
271 INDIGO = 'indigo'
272 PURPLE = 'purple'
273 PINK = 'pink'
274 RED = 'red'
275 ORANGE = 'orange'
276 YELLOW = 'yellow'
277 GREEN = 'green'
278 TEAL = 'teal'
279 CYAN = 'cyan'
280 GRAY = 'gray'
281 BLACK = 'black'
282 WHITE = 'white'
284 CHOICES = (
285 Choice(BLUE, _('Blue')),
286 Choice(INDIGO, _('Indigo')),
287 Choice(PURPLE, _('Purple')),
288 Choice(PINK, _('Pink')),
289 Choice(RED, _('Red')),
290 Choice(ORANGE, _('Orange')),
291 Choice(YELLOW, _('Yellow')),
292 Choice(GREEN, _('Green')),
293 Choice(TEAL, _('Teal')),
294 Choice(CYAN, _('Cyan')),
295 Choice(GRAY, _('Gray')),
296 Choice(BLACK, _('Black')),
297 Choice(WHITE, _('White')),
298 )
301#
302# Event Rules
303#
305class EventRuleActionChoices:
306 """
307 The slugs of NetBox's built-in event rule actions. Not a ChoiceSet: the full, current set of
308 valid action_type values is plugin-extensible and lives in the netbox.event_rules registry,
309 not here -- see get_event_rule_action_choices(). Use these constants for the three built-in
310 actions; do not pass this class itself as a Django/DRF field's `choices=`.
311 """
313 WEBHOOK = 'webhook'
314 SCRIPT = 'script'
315 NOTIFICATION = 'notification'