nautobot 2.3.16__py3-none-any.whl → 2.4.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of nautobot might be problematic. Click here for more details.

Files changed (675) hide show
  1. nautobot/__init__.py +15 -0
  2. nautobot/apps/api.py +0 -2
  3. nautobot/apps/config.py +32 -3
  4. nautobot/apps/events.py +19 -0
  5. nautobot/apps/exceptions.py +0 -2
  6. nautobot/apps/ui.py +44 -9
  7. nautobot/apps/utils.py +0 -8
  8. nautobot/apps/views.py +2 -0
  9. nautobot/circuits/navigation.py +0 -57
  10. nautobot/circuits/tables.py +1 -2
  11. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
  12. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
  13. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
  15. nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
  16. nautobot/circuits/tests/integration/test_relationships.py +33 -24
  17. nautobot/circuits/tests/test_filters.py +4 -8
  18. nautobot/circuits/views.py +143 -26
  19. nautobot/cloud/factory.py +4 -1
  20. nautobot/cloud/models.py +1 -1
  21. nautobot/cloud/tests/test_filters.py +5 -4
  22. nautobot/core/api/fields.py +5 -5
  23. nautobot/core/api/metadata.py +28 -256
  24. nautobot/core/api/pagination.py +3 -2
  25. nautobot/core/api/renderers.py +3 -0
  26. nautobot/core/api/serializers.py +24 -244
  27. nautobot/core/api/urls.py +3 -4
  28. nautobot/core/api/utils.py +0 -62
  29. nautobot/core/api/views.py +48 -158
  30. nautobot/core/apps/__init__.py +22 -578
  31. nautobot/core/celery/__init__.py +13 -0
  32. nautobot/core/celery/log.py +4 -4
  33. nautobot/core/celery/schedulers.py +48 -3
  34. nautobot/core/cli/__init__.py +8 -0
  35. nautobot/core/constants.py +7 -0
  36. nautobot/core/events/__init__.py +116 -0
  37. nautobot/core/events/base.py +27 -0
  38. nautobot/core/events/exceptions.py +10 -0
  39. nautobot/core/events/redis_broker.py +48 -0
  40. nautobot/core/events/syslog_broker.py +19 -0
  41. nautobot/core/exceptions.py +0 -6
  42. nautobot/core/filters.py +16 -21
  43. nautobot/core/fixtures/user-data.json +59 -0
  44. nautobot/core/forms/fields.py +53 -8
  45. nautobot/core/forms/utils.py +2 -1
  46. nautobot/core/graphql/schema.py +3 -1
  47. nautobot/core/graphql/types.py +1 -1
  48. nautobot/core/jobs/__init__.py +4 -4
  49. nautobot/core/jobs/cleanup.py +13 -49
  50. nautobot/core/jobs/groups.py +1 -1
  51. nautobot/core/management/commands/generate_test_data.py +21 -0
  52. nautobot/core/management/commands/validate_models.py +1 -1
  53. nautobot/core/middleware.py +16 -0
  54. nautobot/core/models/__init__.py +1 -1
  55. nautobot/core/models/fields.py +11 -7
  56. nautobot/core/models/query_functions.py +2 -2
  57. nautobot/core/models/tree_queries.py +3 -6
  58. nautobot/core/settings.py +44 -7
  59. nautobot/core/settings.yaml +86 -8
  60. nautobot/core/tables.py +15 -65
  61. nautobot/core/tasks.py +1 -1
  62. nautobot/core/templates/components/button/default.html +7 -0
  63. nautobot/core/templates/components/button/dropdown.html +20 -0
  64. nautobot/core/templates/components/layout/one_over_two.html +19 -0
  65. nautobot/core/templates/components/layout/two_over_one.html +19 -0
  66. nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
  67. nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
  68. nautobot/core/templates/components/panel/body_content_tags.html +6 -0
  69. nautobot/core/templates/components/panel/body_content_text.html +12 -0
  70. nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
  71. nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
  72. nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
  73. nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
  74. nautobot/core/templates/components/panel/footer_content_table.html +14 -0
  75. nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
  76. nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
  77. nautobot/core/templates/components/panel/panel.html +16 -0
  78. nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
  79. nautobot/core/templates/components/tab/content_wrapper.html +3 -0
  80. nautobot/core/templates/components/tab/label_wrapper.html +5 -0
  81. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
  82. nautobot/core/templates/generic/object_retrieve.html +28 -17
  83. nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
  84. nautobot/core/templates/inc/custom_fields/panel.html +2 -2
  85. nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
  86. nautobot/core/templates/inc/footer.html +1 -0
  87. nautobot/core/templates/inc/media.html +0 -3
  88. nautobot/core/templates/inc/nav_menu.html +1 -1
  89. nautobot/core/templates/inc/relationships_panel.html +1 -1
  90. nautobot/core/templates/nautobot_config.py.j2 +3 -3
  91. nautobot/core/templates/panel_table.html +12 -0
  92. nautobot/core/templates/search.html +0 -7
  93. nautobot/core/templates/utilities/render_jinja2.html +117 -0
  94. nautobot/core/templatetags/helpers.py +101 -12
  95. nautobot/core/templatetags/ui_framework.py +40 -0
  96. nautobot/core/testing/api.py +23 -128
  97. nautobot/core/testing/context.py +18 -0
  98. nautobot/core/testing/filters.py +41 -58
  99. nautobot/core/testing/mixins.py +2 -7
  100. nautobot/core/testing/views.py +25 -123
  101. nautobot/core/tests/integration/test_app_home.py +1 -0
  102. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  103. nautobot/core/tests/integration/test_filters.py +2 -0
  104. nautobot/core/tests/integration/test_home.py +1 -0
  105. nautobot/core/tests/integration/test_navbar.py +1 -0
  106. nautobot/core/tests/integration/test_view_authentication.py +1 -2
  107. nautobot/core/tests/nautobot_config.py +198 -0
  108. nautobot/core/tests/runner.py +3 -3
  109. nautobot/core/tests/test_api.py +82 -201
  110. nautobot/core/tests/test_csv.py +3 -25
  111. nautobot/core/tests/test_events.py +214 -0
  112. nautobot/core/tests/test_jinja_filters.py +1 -0
  113. nautobot/core/tests/test_jobs.py +84 -13
  114. nautobot/core/tests/test_navigations.py +7 -241
  115. nautobot/core/tests/test_templatetags_helpers.py +16 -0
  116. nautobot/core/tests/test_ui.py +150 -0
  117. nautobot/core/tests/test_utils.py +0 -25
  118. nautobot/core/tests/test_views.py +123 -31
  119. nautobot/core/ui/__init__.py +0 -0
  120. nautobot/core/ui/base.py +11 -0
  121. nautobot/core/ui/choices.py +44 -0
  122. nautobot/core/ui/homepage.py +167 -0
  123. nautobot/core/ui/nav.py +279 -0
  124. nautobot/core/ui/object_detail.py +1841 -0
  125. nautobot/core/ui/utils.py +36 -0
  126. nautobot/core/urls.py +4 -9
  127. nautobot/core/utils/config.py +30 -3
  128. nautobot/core/utils/lookup.py +20 -13
  129. nautobot/core/views/__init__.py +6 -1
  130. nautobot/core/views/generic.py +47 -52
  131. nautobot/core/views/mixins.py +15 -25
  132. nautobot/core/views/paginator.py +8 -5
  133. nautobot/core/views/renderers.py +3 -3
  134. nautobot/core/views/utils.py +11 -0
  135. nautobot/core/wsgi.py +3 -3
  136. nautobot/dcim/api/serializers.py +80 -179
  137. nautobot/dcim/api/urls.py +5 -0
  138. nautobot/dcim/api/views.py +17 -4
  139. nautobot/dcim/apps.py +1 -0
  140. nautobot/dcim/choices.py +28 -0
  141. nautobot/dcim/factory.py +58 -0
  142. nautobot/dcim/filters/__init__.py +197 -24
  143. nautobot/dcim/forms.py +203 -12
  144. nautobot/dcim/graphql/types.py +2 -2
  145. nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
  146. nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
  147. nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
  148. nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
  149. nautobot/dcim/models/__init__.py +4 -0
  150. nautobot/dcim/models/device_component_templates.py +2 -2
  151. nautobot/dcim/models/device_components.py +20 -22
  152. nautobot/dcim/models/devices.py +173 -4
  153. nautobot/dcim/models/locations.py +3 -3
  154. nautobot/dcim/models/power.py +5 -6
  155. nautobot/dcim/models/racks.py +6 -6
  156. nautobot/dcim/navigation.py +25 -224
  157. nautobot/dcim/signals.py +44 -0
  158. nautobot/dcim/tables/__init__.py +5 -3
  159. nautobot/dcim/tables/devices.py +96 -2
  160. nautobot/dcim/tables/devicetypes.py +2 -2
  161. nautobot/dcim/templates/dcim/controller/base.html +10 -0
  162. nautobot/dcim/templates/dcim/controller_create.html +1 -0
  163. nautobot/dcim/templates/dcim/controller_retrieve.html +5 -1
  164. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
  165. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +66 -0
  166. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +46 -0
  167. nautobot/dcim/templates/dcim/device/base.html +6 -42
  168. nautobot/dcim/templates/dcim/device/wireless.html +73 -0
  169. nautobot/dcim/templates/dcim/device.html +3 -1
  170. nautobot/dcim/templates/dcim/interface.html +1 -0
  171. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  172. nautobot/dcim/templates/dcim/locationtype.html +0 -107
  173. nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
  174. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +76 -0
  175. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +34 -0
  176. nautobot/dcim/tests/test_api.py +172 -61
  177. nautobot/dcim/tests/test_filters.py +171 -109
  178. nautobot/dcim/tests/test_forms.py +2 -51
  179. nautobot/dcim/tests/test_graphql.py +0 -52
  180. nautobot/dcim/tests/test_models.py +126 -4
  181. nautobot/dcim/tests/test_signals.py +1 -0
  182. nautobot/dcim/tests/test_views.py +103 -11
  183. nautobot/dcim/urls.py +72 -27
  184. nautobot/dcim/utils.py +2 -2
  185. nautobot/dcim/views.py +369 -62
  186. nautobot/extras/api/customfields.py +2 -2
  187. nautobot/extras/api/serializers.py +91 -75
  188. nautobot/extras/api/urls.py +4 -0
  189. nautobot/extras/api/views.py +78 -15
  190. nautobot/extras/choices.py +13 -0
  191. nautobot/extras/constants.py +0 -1
  192. nautobot/extras/context_managers.py +23 -6
  193. nautobot/extras/datasources/git.py +4 -1
  194. nautobot/extras/factory.py +27 -0
  195. nautobot/extras/filters/__init__.py +59 -0
  196. nautobot/extras/forms/forms.py +125 -30
  197. nautobot/extras/forms/mixins.py +3 -11
  198. nautobot/extras/graphql/types.py +25 -1
  199. nautobot/extras/group_sync.py +3 -3
  200. nautobot/extras/health_checks.py +2 -1
  201. nautobot/extras/jobs.py +62 -26
  202. nautobot/extras/management/__init__.py +1 -0
  203. nautobot/extras/management/commands/runjob.py +7 -79
  204. nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
  205. nautobot/extras/management/utils.py +87 -0
  206. nautobot/extras/managers.py +1 -3
  207. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  208. nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
  209. nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
  210. nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
  211. nautobot/extras/models/__init__.py +4 -0
  212. nautobot/extras/models/change_logging.py +7 -3
  213. nautobot/extras/models/customfields.py +11 -12
  214. nautobot/extras/models/groups.py +9 -13
  215. nautobot/extras/models/jobs.py +218 -37
  216. nautobot/extras/models/models.py +2 -2
  217. nautobot/extras/models/relationships.py +69 -1
  218. nautobot/extras/models/secrets.py +5 -0
  219. nautobot/extras/navigation.py +20 -262
  220. nautobot/extras/plugins/__init__.py +56 -32
  221. nautobot/extras/plugins/marketplace_manifest.yml +450 -0
  222. nautobot/extras/plugins/urls.py +1 -0
  223. nautobot/extras/plugins/views.py +48 -1
  224. nautobot/extras/signals.py +39 -1
  225. nautobot/extras/tables.py +40 -6
  226. nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
  227. nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
  228. nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
  229. nautobot/extras/templates/extras/job_detail.html +36 -6
  230. nautobot/extras/templates/extras/job_edit.html +5 -2
  231. nautobot/extras/templates/extras/job_list.html +2 -7
  232. nautobot/extras/templates/extras/jobqueue_retrieve.html +44 -0
  233. nautobot/extras/templates/extras/marketplace.html +278 -0
  234. nautobot/extras/templates/extras/plugins_list.html +35 -1
  235. nautobot/extras/templates/extras/plugins_tiles.html +79 -0
  236. nautobot/extras/templates/extras/role_retrieve.html +16 -0
  237. nautobot/extras/templates/extras/secret.html +0 -65
  238. nautobot/extras/templates/extras/secret_check.js +16 -0
  239. nautobot/extras/templates/extras/secret_create.html +114 -0
  240. nautobot/extras/templates/extras/secret_edit.html +1 -114
  241. nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
  242. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
  243. nautobot/extras/templatetags/job_buttons.py +5 -4
  244. nautobot/extras/templatetags/plugins.py +69 -6
  245. nautobot/extras/test_jobs/api_test_job.py +1 -1
  246. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  247. nautobot/extras/test_jobs/dry_run.py +1 -1
  248. nautobot/extras/test_jobs/fail.py +5 -5
  249. nautobot/extras/test_jobs/file_output.py +1 -1
  250. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  251. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  252. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  253. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  254. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  255. nautobot/extras/test_jobs/log_redaction.py +1 -1
  256. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  257. nautobot/extras/test_jobs/modify_db.py +1 -1
  258. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  259. nautobot/extras/test_jobs/object_var_required.py +1 -1
  260. nautobot/extras/test_jobs/object_vars.py +1 -1
  261. nautobot/extras/test_jobs/pass.py +3 -3
  262. nautobot/extras/test_jobs/profiling.py +1 -1
  263. nautobot/extras/test_jobs/relative_import.py +3 -3
  264. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  265. nautobot/extras/test_jobs/task_queues.py +1 -1
  266. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  267. nautobot/extras/tests/test_api.py +157 -55
  268. nautobot/extras/tests/test_context_managers.py +4 -1
  269. nautobot/extras/tests/test_customfields.py +1 -1
  270. nautobot/extras/tests/test_datasources.py +1 -2
  271. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  272. nautobot/extras/tests/test_filters.py +219 -535
  273. nautobot/extras/tests/test_forms.py +1 -20
  274. nautobot/extras/tests/test_job_variables.py +73 -152
  275. nautobot/extras/tests/test_jobs.py +43 -54
  276. nautobot/extras/tests/test_models.py +71 -16
  277. nautobot/extras/tests/test_relationships.py +5 -2
  278. nautobot/extras/tests/test_utils.py +23 -2
  279. nautobot/extras/tests/test_views.py +183 -43
  280. nautobot/extras/tests/test_webhooks.py +2 -1
  281. nautobot/extras/urls.py +2 -20
  282. nautobot/extras/utils.py +118 -4
  283. nautobot/extras/views.py +203 -92
  284. nautobot/extras/webhooks.py +5 -2
  285. nautobot/ipam/api/fields.py +3 -3
  286. nautobot/ipam/api/serializers.py +36 -137
  287. nautobot/ipam/api/views.py +93 -62
  288. nautobot/ipam/lookups.py +62 -101
  289. nautobot/ipam/models.py +11 -63
  290. nautobot/ipam/navigation.py +0 -90
  291. nautobot/ipam/querysets.py +2 -2
  292. nautobot/ipam/tables.py +6 -20
  293. nautobot/ipam/templates/ipam/routetarget.html +0 -28
  294. nautobot/ipam/templates/ipam/vrf.html +0 -47
  295. nautobot/ipam/tests/test_api.py +8 -419
  296. nautobot/ipam/tests/test_filters.py +39 -119
  297. nautobot/ipam/tests/test_forms.py +47 -51
  298. nautobot/ipam/tests/test_migrations.py +30 -30
  299. nautobot/ipam/tests/test_models.py +0 -41
  300. nautobot/ipam/tests/test_querysets.py +1 -63
  301. nautobot/ipam/urls.py +3 -69
  302. nautobot/ipam/utils/__init__.py +0 -24
  303. nautobot/ipam/views.py +153 -198
  304. nautobot/project-static/css/base.css +38 -3
  305. nautobot/project-static/docs/404.html +421 -19
  306. nautobot/project-static/docs/apps/index.html +421 -19
  307. nautobot/project-static/docs/apps/nautobot-apps.html +421 -19
  308. nautobot/project-static/docs/assets/extra.css +5 -1
  309. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  310. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  311. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +421 -19
  312. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +421 -19
  313. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +421 -172
  314. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +421 -19
  315. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +421 -19
  316. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +425 -21
  317. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +421 -19
  318. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +424 -22
  319. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9809 -0
  320. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +424 -63
  321. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +421 -19
  322. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +421 -19
  323. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +457 -20
  324. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +421 -19
  325. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +425 -25
  326. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +457 -19
  327. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +421 -19
  328. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +421 -19
  329. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +425 -215
  330. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +430 -342
  331. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5799 -1054
  332. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +421 -19
  333. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +447 -176
  334. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +460 -21
  335. nautobot/project-static/docs/development/apps/api/configuration-view.html +421 -19
  336. nautobot/project-static/docs/development/apps/api/database-backend-config.html +421 -19
  337. nautobot/project-static/docs/development/apps/api/models/django-admin.html +421 -19
  338. nautobot/project-static/docs/development/apps/api/models/global-search.html +421 -19
  339. nautobot/project-static/docs/development/apps/api/models/graphql.html +421 -19
  340. nautobot/project-static/docs/development/apps/api/models/index.html +421 -19
  341. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +421 -19
  342. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +421 -19
  343. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +421 -19
  344. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +421 -19
  345. nautobot/project-static/docs/development/apps/api/platform-features/index.html +421 -19
  346. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +421 -19
  347. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +421 -19
  348. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +421 -19
  349. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +421 -19
  350. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +424 -41
  351. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +421 -19
  352. nautobot/project-static/docs/development/apps/api/prometheus.html +421 -19
  353. nautobot/project-static/docs/development/apps/api/setup.html +425 -155
  354. nautobot/project-static/docs/development/apps/api/testing.html +421 -19
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +421 -19
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +421 -19
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +421 -19
  358. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +421 -19
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +701 -130
  360. nautobot/project-static/docs/development/apps/api/views/base-template.html +421 -19
  361. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +421 -19
  362. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +421 -19
  363. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +421 -19
  364. nautobot/project-static/docs/development/apps/api/views/index.html +423 -20
  365. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +425 -19
  366. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +451 -19
  367. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +421 -19
  368. nautobot/project-static/docs/development/apps/api/views/notes.html +421 -19
  369. nautobot/project-static/docs/development/apps/api/views/rest-api.html +421 -19
  370. nautobot/project-static/docs/development/apps/api/views/urls.html +421 -19
  371. nautobot/project-static/docs/development/apps/index.html +421 -19
  372. nautobot/project-static/docs/development/apps/migration/code-updates.html +422 -52
  373. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +422 -20
  374. nautobot/project-static/docs/development/apps/migration/from-v1.html +421 -19
  375. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +421 -19
  376. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +421 -19
  377. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +421 -19
  378. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +424 -22
  379. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9219 -0
  380. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9333 -0
  381. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9474 -0
  382. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9517 -0
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +424 -22
  384. nautobot/project-static/docs/development/core/application-registry.html +421 -19
  385. nautobot/project-static/docs/development/core/best-practices.html +421 -19
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +421 -19
  387. nautobot/project-static/docs/development/core/caching.html +421 -19
  388. nautobot/project-static/docs/development/core/controllers.html +423 -19
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +490 -45
  390. nautobot/project-static/docs/development/core/generic-views.html +421 -19
  391. nautobot/project-static/docs/development/core/getting-started.html +566 -179
  392. nautobot/project-static/docs/development/core/homepage.html +432 -30
  393. nautobot/project-static/docs/development/core/index.html +421 -19
  394. nautobot/project-static/docs/development/core/local-k8s.html +9453 -0
  395. nautobot/project-static/docs/development/core/model-checklist.html +424 -22
  396. nautobot/project-static/docs/development/core/model-features.html +421 -19
  397. nautobot/project-static/docs/development/core/natural-keys.html +421 -19
  398. nautobot/project-static/docs/development/core/navigation-menu.html +438 -26
  399. nautobot/project-static/docs/development/core/release-checklist.html +435 -45
  400. nautobot/project-static/docs/development/core/role-internals.html +421 -19
  401. nautobot/project-static/docs/development/core/settings.html +421 -19
  402. nautobot/project-static/docs/development/core/style-guide.html +421 -19
  403. nautobot/project-static/docs/development/core/templates.html +431 -22
  404. nautobot/project-static/docs/development/core/testing.html +421 -19
  405. nautobot/project-static/docs/development/core/ui-component-framework.html +11020 -0
  406. nautobot/project-static/docs/development/core/user-preferences.html +424 -22
  407. nautobot/project-static/docs/development/index.html +421 -19
  408. nautobot/project-static/docs/development/jobs/index.html +546 -160
  409. nautobot/project-static/docs/development/jobs/migration/from-v1.html +421 -19
  410. nautobot/project-static/docs/index.html +421 -19
  411. nautobot/project-static/docs/media/development/core/ui-component-framework/basic-panel-layout.png +0 -0
  412. nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.png +0 -0
  413. nautobot/project-static/docs/media/development/core/ui-component-framework/dropdown-button-example.png +0 -0
  414. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
  415. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
  416. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example.png +0 -0
  417. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
  418. nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
  419. nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
  420. nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
  421. nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
  422. nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
  423. nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
  424. nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
  425. nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
  426. nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
  427. nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +426 -20
  430. nautobot/project-static/docs/overview/design_philosophy.html +421 -19
  431. nautobot/project-static/docs/release-notes/index.html +445 -22
  432. nautobot/project-static/docs/release-notes/version-1.0.html +421 -19
  433. nautobot/project-static/docs/release-notes/version-1.1.html +421 -19
  434. nautobot/project-static/docs/release-notes/version-1.2.html +421 -19
  435. nautobot/project-static/docs/release-notes/version-1.3.html +421 -19
  436. nautobot/project-static/docs/release-notes/version-1.4.html +421 -19
  437. nautobot/project-static/docs/release-notes/version-1.5.html +421 -19
  438. nautobot/project-static/docs/release-notes/version-1.6.html +634 -667
  439. nautobot/project-static/docs/release-notes/version-2.0.html +421 -19
  440. nautobot/project-static/docs/release-notes/version-2.1.html +421 -19
  441. nautobot/project-static/docs/release-notes/version-2.2.html +421 -19
  442. nautobot/project-static/docs/release-notes/version-2.3.html +684 -886
  443. nautobot/project-static/docs/release-notes/version-2.4.html +10007 -0
  444. nautobot/project-static/docs/requirements.txt +2 -2
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +334 -270
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +421 -19
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +421 -19
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +423 -21
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +433 -32
  452. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +421 -19
  453. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +765 -180
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +421 -19
  455. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +421 -19
  456. nautobot/project-static/docs/user-guide/administration/guides/docker.html +434 -29
  457. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +421 -19
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +421 -19
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +421 -19
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +421 -19
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +421 -19
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +421 -19
  463. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +421 -19
  464. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +421 -19
  465. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +421 -19
  466. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +421 -19
  467. nautobot/project-static/docs/user-guide/administration/installation/index.html +426 -20
  468. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +421 -19
  469. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +421 -19
  470. nautobot/project-static/docs/user-guide/administration/installation/services.html +421 -19
  471. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +421 -19
  472. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +442 -41
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +435 -66
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +435 -66
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +421 -19
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +421 -19
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +421 -19
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +421 -19
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +421 -19
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +421 -19
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +421 -19
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +421 -19
  484. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +427 -21
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +421 -19
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +421 -19
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +421 -19
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +421 -19
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +421 -19
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +421 -19
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +421 -19
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +421 -19
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +421 -19
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +421 -19
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +421 -19
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +421 -19
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +421 -19
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +421 -19
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +421 -19
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +421 -19
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +421 -19
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +457 -20
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +447 -22
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +421 -19
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +421 -19
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +421 -19
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +421 -19
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +421 -19
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +421 -19
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +421 -19
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +421 -19
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +421 -19
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +421 -19
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +421 -19
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +421 -19
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +421 -19
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +421 -19
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +421 -19
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +421 -19
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +421 -19
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +421 -19
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +421 -19
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +421 -19
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +421 -19
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +421 -19
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +421 -19
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +421 -19
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +421 -19
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +421 -19
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +421 -19
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +421 -19
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +421 -19
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +421 -19
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +421 -19
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +421 -19
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +421 -19
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +421 -19
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9333 -0
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +424 -22
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +421 -19
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +421 -19
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +421 -19
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +421 -19
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +421 -19
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +421 -19
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +421 -19
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +421 -19
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +421 -19
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +421 -19
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +421 -19
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +421 -19
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +421 -19
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +421 -19
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +421 -19
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +421 -19
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +421 -19
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +421 -19
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +421 -19
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +424 -22
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9271 -0
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9175 -0
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9169 -0
  563. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9235 -0
  564. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +421 -19
  565. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +421 -19
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +421 -19
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +421 -19
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +421 -19
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +421 -19
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +421 -19
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +421 -19
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +421 -19
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +421 -19
  574. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +421 -19
  575. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +421 -19
  576. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +421 -19
  577. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +421 -19
  578. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +421 -19
  579. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +421 -19
  580. nautobot/project-static/docs/user-guide/index.html +421 -19
  581. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +424 -22
  582. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +421 -19
  583. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +421 -19
  584. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +421 -19
  585. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +421 -19
  586. nautobot/project-static/docs/user-guide/platform-functionality/events.html +9575 -0
  587. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +424 -22
  588. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +421 -19
  589. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +421 -19
  590. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +421 -19
  591. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +421 -19
  592. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +421 -19
  593. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +426 -20
  594. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +424 -22
  595. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +421 -19
  596. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +421 -19
  597. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9182 -0
  598. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +424 -22
  599. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +421 -19
  600. nautobot/project-static/docs/user-guide/platform-functionality/note.html +421 -19
  601. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +421 -19
  602. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +424 -22
  603. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9250 -0
  604. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +421 -19
  605. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +421 -19
  606. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +424 -22
  607. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +421 -19
  608. nautobot/project-static/docs/user-guide/platform-functionality/role.html +421 -19
  609. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +421 -19
  610. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +421 -19
  611. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +424 -22
  612. nautobot/project-static/docs/user-guide/platform-functionality/status.html +421 -19
  613. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +421 -19
  614. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +489 -56
  615. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +421 -19
  616. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +421 -19
  617. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +421 -19
  618. nautobot/project-static/img/jinja_logo.svg +97 -0
  619. nautobot/project-static/js/forms.js +5 -0
  620. nautobot/project-static/js/nav_menu.js +2 -1
  621. nautobot/tenancy/api/serializers.py +0 -2
  622. nautobot/tenancy/factory.py +1 -1
  623. nautobot/tenancy/navigation.py +0 -29
  624. nautobot/tenancy/templates/tenancy/tenant.html +4 -91
  625. nautobot/tenancy/tests/test_filters.py +29 -134
  626. nautobot/tenancy/views.py +32 -23
  627. nautobot/users/admin.py +3 -1
  628. nautobot/users/api/serializers.py +4 -5
  629. nautobot/users/api/views.py +1 -1
  630. nautobot/users/forms.py +19 -0
  631. nautobot/users/templates/users/preferences.html +22 -0
  632. nautobot/users/tests/test_filters.py +1 -19
  633. nautobot/users/tests/test_views.py +57 -0
  634. nautobot/users/utils.py +8 -0
  635. nautobot/users/views.py +48 -11
  636. nautobot/virtualization/api/serializers.py +4 -4
  637. nautobot/virtualization/filters.py +2 -20
  638. nautobot/virtualization/navigation.py +0 -48
  639. nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
  640. nautobot/virtualization/tests/test_filters.py +57 -183
  641. nautobot/virtualization/views.py +18 -15
  642. nautobot/wireless/__init__.py +0 -0
  643. nautobot/wireless/api/__init__.py +0 -0
  644. nautobot/wireless/api/serializers.py +44 -0
  645. nautobot/wireless/api/urls.py +20 -0
  646. nautobot/wireless/api/views.py +34 -0
  647. nautobot/wireless/apps.py +8 -0
  648. nautobot/wireless/choices.py +345 -0
  649. nautobot/wireless/factory.py +138 -0
  650. nautobot/wireless/filters.py +167 -0
  651. nautobot/wireless/forms.py +283 -0
  652. nautobot/wireless/homepage.py +19 -0
  653. nautobot/wireless/migrations/0001_initial.py +223 -0
  654. nautobot/wireless/migrations/__init__.py +0 -0
  655. nautobot/wireless/models.py +207 -0
  656. nautobot/wireless/navigation.py +105 -0
  657. nautobot/wireless/tables.py +244 -0
  658. nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
  659. nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
  660. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
  661. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +64 -0
  662. nautobot/wireless/tests/__init__.py +0 -0
  663. nautobot/wireless/tests/test_api.py +247 -0
  664. nautobot/wireless/tests/test_filters.py +54 -0
  665. nautobot/wireless/tests/test_models.py +22 -0
  666. nautobot/wireless/tests/test_views.py +378 -0
  667. nautobot/wireless/urls.py +13 -0
  668. nautobot/wireless/views.py +129 -0
  669. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +11 -14
  670. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +674 -551
  671. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  672. nautobot/core/utils/navigation.py +0 -54
  673. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  674. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  675. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
@@ -43,7 +43,8 @@ def parse_numeric_range(input_string, base=10):
43
43
  begin, end = dash_range, dash_range
44
44
  begin, end = int(begin.strip(), base=base), int(end.strip(), base=base) + 1
45
45
  values.extend(range(begin, end))
46
- return sorted(list(set(values)))
46
+ # Remove duplicates and sort
47
+ return sorted(set(values))
47
48
 
48
49
 
49
50
  def parse_alphanumeric_range(string):
@@ -43,7 +43,7 @@ from nautobot.dcim.graphql.types import (
43
43
  RearPortType,
44
44
  )
45
45
  from nautobot.extras.choices import CustomFieldTypeChoices, RelationshipSideChoices
46
- from nautobot.extras.graphql.types import ContactAssociationType, DynamicGroupType, TagType
46
+ from nautobot.extras.graphql.types import ContactAssociationType, DynamicGroupType, JobType, ScheduledJobType, TagType
47
47
  from nautobot.extras.models import ComputedField, CustomField, Relationship
48
48
  from nautobot.extras.registry import registry
49
49
  from nautobot.extras.utils import check_if_key_is_graphql_safe
@@ -71,6 +71,8 @@ registry["graphql_types"]["dcim.rearport"] = RearPortType
71
71
  registry["graphql_types"]["dcim.location"] = LocationType
72
72
  registry["graphql_types"]["extras.contactassociation"] = ContactAssociationType
73
73
  registry["graphql_types"]["extras.dynamicgroup"] = DynamicGroupType
74
+ registry["graphql_types"]["extras.job"] = JobType
75
+ registry["graphql_types"]["extras.scheduledjob"] = ScheduledJobType
74
76
  registry["graphql_types"]["extras.tag"] = TagType
75
77
  registry["graphql_types"]["ipam.ipaddress"] = IPAddressType
76
78
  registry["graphql_types"]["ipam.prefix"] = PrefixType
@@ -10,7 +10,7 @@ class OptimizedNautobotObjectType(gql_optimizer.OptimizedDjangoObjectType):
10
10
  url = graphene.String()
11
11
 
12
12
  def resolve_url(self, info):
13
- return self.get_absolute_url(api=True) # pylint: disable=no-member
13
+ return self.get_absolute_url(api=True)
14
14
 
15
15
  class Meta:
16
16
  abstract = True
@@ -47,7 +47,7 @@ class GitRepositorySync(Job):
47
47
  description = "Clone and/or pull a Git repository, then refresh data sourced from this repository."
48
48
  has_sensitive_variables = False
49
49
 
50
- def run(self, repository): # pylint:disable=arguments-differ
50
+ def run(self, repository):
51
51
  job_result = self.job_result
52
52
  user = job_result.user
53
53
 
@@ -88,7 +88,7 @@ class GitRepositoryDryRun(Job):
88
88
  description = "Dry run of Git repository sync - will not update data sourced from this repository."
89
89
  has_sensitive_variables = False
90
90
 
91
- def run(self, repository): # pylint:disable=arguments-differ
91
+ def run(self, repository):
92
92
  job_result = self.job_result
93
93
  self.logger.info(f'Performing a Dry Run on Git repository "{repository.name}"...')
94
94
 
@@ -138,7 +138,7 @@ class ExportObjectList(Job):
138
138
  soft_time_limit = 1800
139
139
  time_limit = 2000
140
140
 
141
- def run(self, *, content_type, query_string="", export_format="csv", export_template=None): # pylint:disable=arguments-differ
141
+ def run(self, *, content_type, query_string="", export_format="csv", export_template=None):
142
142
  if not self.user.has_perm(f"{content_type.app_label}.view_{content_type.model}"):
143
143
  self.logger.error('User "%s" does not have permission to view %s objects', self.user, content_type.model)
144
144
  raise PermissionDenied("User does not have view permissions on the requested content-type")
@@ -286,7 +286,7 @@ class ImportObjects(Job):
286
286
  self.logger.error("Row %d: `%s`: `%s`", row, field, err[0])
287
287
  return new_objs, validation_failed
288
288
 
289
- def run(self, *, content_type, csv_data=None, csv_file=None, roll_back_if_error=False): # pylint:disable=arguments-differ
289
+ def run(self, *, content_type, csv_data=None, csv_file=None, roll_back_if_error=False):
290
290
  if not self.user.has_perm(f"{content_type.app_label}.add_{content_type.model}"):
291
291
  self.logger.error('User "%s" does not have permission to create %s objects', self.user, content_type.model)
292
292
  raise PermissionDenied("User does not have create permissions on the requested content-type")
@@ -1,7 +1,6 @@
1
1
  from datetime import timedelta
2
2
 
3
3
  from django.core.exceptions import PermissionDenied
4
- from django.db.models import CASCADE
5
4
  from django.db.models.signals import pre_delete
6
5
  from django.utils import timezone
7
6
 
@@ -49,30 +48,9 @@ class LogsCleanup(Job):
49
48
  description = "Delete ObjectChange and/or JobResult/JobLogEntry records older than a specified cutoff."
50
49
  has_sensitive_variables = False
51
50
 
52
- def recursive_delete_with_cascade(self, queryset, deletion_summary):
53
- """
54
- Recursively deletes all related objects with CASCADE for a given queryset.
55
-
56
- Args:
57
- queryset (QuerySet): The queryset of objects to delete.
58
- deletion_summary (dict): A dictionary to store the count of deleted objects for each model.
59
- """
60
- related_objects = queryset.model._meta.related_objects
61
- queryset = queryset.only("id")
62
-
63
- for related_object in related_objects:
64
- if related_object.on_delete is CASCADE:
65
- related_model = related_object.related_model
66
- related_field_name = related_object.field.name
67
- cascade_queryset = related_model.objects.filter(**{f"{related_field_name}__id__in": queryset})
68
- self.recursive_delete_with_cascade(cascade_queryset, deletion_summary)
69
- _, deleted_dict = queryset.delete()
70
- deletion_summary.update(deleted_dict)
71
- return deletion_summary
72
-
73
- def run(self, *, cleanup_types, max_age=None): # pylint: disable=arguments-differ
51
+ def run(self, *, cleanup_types, max_age=None):
74
52
  if max_age in (None, ""):
75
- max_age = get_settings_or_config("CHANGELOG_RETENTION")
53
+ max_age = get_settings_or_config("CHANGELOG_RETENTION", fallback=90)
76
54
  if max_age == 0:
77
55
  self.logger.warning(
78
56
  "CHANGELOG_RETENTION setting is set to zero, disabling this Job. "
@@ -99,36 +77,22 @@ class LogsCleanup(Job):
99
77
 
100
78
  if CleanupTypes.JOB_RESULT in cleanup_types:
101
79
  self.logger.info("Deleting JobResult records prior to %s", cutoff)
102
- queryset = JobResult.objects.restrict(self.user, "delete").filter(date_done__lt=cutoff)
103
- deletion_summary = {}
104
- self.recursive_delete_with_cascade(queryset, deletion_summary)
80
+ _, deleted_dict = JobResult.objects.restrict(self.user, "delete").filter(date_done__lt=cutoff).delete()
105
81
  result.setdefault("extras.JobResult", 0)
106
82
  result.setdefault("extras.JobLogEntry", 0)
107
- result.update(deletion_summary)
108
-
109
- for modelname, count in deletion_summary.items():
110
- self.logger.info(
111
- "As part of deleting %d JobResult records, also deleted %d related %s records",
112
- result["extras.JobResult"],
113
- count,
114
- modelname,
115
- )
83
+ result.update(**deleted_dict)
84
+ self.logger.info(
85
+ "Deleted %d JobResult records and their associated %d JobLogEntry records",
86
+ result["extras.JobResult"],
87
+ result["extras.JobLogEntry"],
88
+ )
116
89
 
117
90
  if CleanupTypes.OBJECT_CHANGE in cleanup_types:
118
91
  self.logger.info("Deleting ObjectChange records prior to %s", cutoff)
119
- queryset = ObjectChange.objects.restrict(self.user, "delete").filter(time__lt=cutoff)
120
- deletion_summary = {}
121
- self.recursive_delete_with_cascade(queryset, deletion_summary)
122
- result.setdefault("extras.ObjectChange", 0)
123
- result.update(deletion_summary)
124
-
125
- for modelname, count in deletion_summary.items():
126
- self.logger.info(
127
- "As part of deleting %d ObjectChange records, also deleted %d related %s records",
128
- result["extras.ObjectChange"],
129
- count,
130
- modelname,
131
- )
92
+ deleted_count, _ = ObjectChange.objects.restrict(self.user, "delete").filter(time__lt=cutoff).delete()
93
+ self.logger.info("Deleted %d ObjectChange records", deleted_count)
94
+ result["extras.ObjectChange"] = deleted_count
95
+
132
96
  return result
133
97
  finally:
134
98
  # Be sure to clean up after ourselves!
@@ -24,7 +24,7 @@ class RefreshDynamicGroupCaches(Job):
24
24
  description = "Re-calculate and re-cache the membership lists of Dynamic Groups."
25
25
  has_sensitive_variables = False
26
26
 
27
- def run(self, single_group=None): # pylint: disable=arguments-differ
27
+ def run(self, single_group=None):
28
28
  groups = DynamicGroup.objects.restrict(self.user, "view").exclude(
29
29
  group_type=DynamicGroupTypeChoices.TYPE_STATIC
30
30
  )
@@ -98,6 +98,7 @@ class Command(BaseCommand):
98
98
  RearPortTemplateFactory,
99
99
  SoftwareImageFileFactory,
100
100
  SoftwareVersionFactory,
101
+ VirtualDeviceContextFactory,
101
102
  )
102
103
  from nautobot.extras.choices import MetadataTypeDataTypeChoices
103
104
  from nautobot.extras.factory import (
@@ -105,6 +106,7 @@ class Command(BaseCommand):
105
106
  DynamicGroupFactory,
106
107
  ExternalIntegrationFactory,
107
108
  JobLogEntryFactory,
109
+ JobQueueFactory,
108
110
  JobResultFactory,
109
111
  MetadataChoiceFactory,
110
112
  MetadataTypeFactory,
@@ -131,6 +133,14 @@ class Command(BaseCommand):
131
133
  )
132
134
  from nautobot.tenancy.factory import TenantFactory, TenantGroupFactory
133
135
  from nautobot.users.factory import UserFactory
136
+ from nautobot.wireless.factory import (
137
+ ControllerManagedDeviceGroupWithMembersFactory,
138
+ RadioProfileFactory,
139
+ RadioProfilesWithMembersFactory,
140
+ SupportedDataRateFactory,
141
+ WirelessNetworkFactory,
142
+ WirelessNetworksWithMembersFactory,
143
+ )
134
144
  except ImportError as err:
135
145
  raise CommandError('Unable to load data factories. Is the "factory-boy" package installed?') from err
136
146
 
@@ -218,6 +228,7 @@ class Command(BaseCommand):
218
228
  _create_batch(ManufacturerFactory, 2, description="without Platforms or DeviceTypes") # Last 2 hard-coded
219
229
  _create_batch(DeviceRedundancyGroupFactory, 20)
220
230
  _create_batch(DeviceFactory, 20)
231
+ _create_batch(VirtualDeviceContextFactory, 30)
221
232
  _create_batch(ModuleFactory, 20)
222
233
  _create_batch(SoftwareVersionFactory, 5, description="without Devices")
223
234
  _create_batch(SoftwareImageFileFactory, 5, description="without DeviceTypes")
@@ -304,6 +315,15 @@ class Command(BaseCommand):
304
315
  _create_batch(ExternalIntegrationFactory, 20)
305
316
  _create_batch(ControllerFactory, 10, description="with Devices or DeviceRedundancyGroups")
306
317
  _create_batch(ControllerManagedDeviceGroupFactory, 5, description="without any Devices")
318
+ _create_batch(SupportedDataRateFactory, 20)
319
+ _create_batch(RadioProfileFactory, 20)
320
+ _create_batch(WirelessNetworkFactory, 20)
321
+ _create_batch(ControllerManagedDeviceGroupWithMembersFactory, 5, description="with members")
322
+ _create_batch(RadioProfilesWithMembersFactory, 5, description="with members")
323
+ _create_batch(WirelessNetworksWithMembersFactory, 5, description="with members")
324
+ # make sure we have some supported data rates that have null relationships to make filter tests happy
325
+ _create_batch(SupportedDataRateFactory, 10, description="without any associated objects")
326
+ _create_batch(JobQueueFactory, 10)
307
327
  # make sure we have some tenants that have null relationships to make filter tests happy
308
328
  _create_batch(TenantFactory, 10, description="without any associated objects")
309
329
  # TODO: nautobot.tenancy.tests.test_filters currently calls the following additional factories:
@@ -329,6 +349,7 @@ class Command(BaseCommand):
329
349
  )
330
350
  _create_batch(MetadataChoiceFactory, 100)
331
351
  _create_batch(ObjectChangeFactory, 100)
352
+ _create_batch(JobQueueFactory, 30)
332
353
  _create_batch(JobResultFactory, 20)
333
354
  _create_batch(JobLogEntryFactory, 100)
334
355
  _create_batch(ObjectMetadataFactory, 100)
@@ -63,7 +63,7 @@ class Command(BaseCommand):
63
63
  for model in models:
64
64
  model_name = f"{model._meta.app_label}.{model.__name__}"
65
65
  # Most swap out for user_model
66
- if model_name == "auth.User": # pylint: disable=hard-coded-auth-user
66
+ if model_name == "auth.User":
67
67
  model = get_user_model()
68
68
  # Skip models that aren't actually in the database
69
69
  if not model._meta.managed:
@@ -1,9 +1,12 @@
1
+ from zoneinfo import ZoneInfo
2
+
1
3
  from django.conf import settings
2
4
  from django.contrib.auth.middleware import RemoteUserMiddleware as RemoteUserMiddleware_
3
5
  from django.db import ProgrammingError
4
6
  from django.http import Http404
5
7
  from django.urls import resolve
6
8
  from django.urls.exceptions import Resolver404
9
+ from django.utils import timezone
7
10
  from django.utils.deprecation import MiddlewareMixin
8
11
 
9
12
  from nautobot.core.api.utils import is_api_request, rest_api_server_error
@@ -149,3 +152,16 @@ class ExceptionHandlingMiddleware:
149
152
  return server_error(request, template_name=custom_template)
150
153
 
151
154
  return None
155
+
156
+
157
+ class UserDefinedTimeZoneMiddleware:
158
+ def __init__(self, get_response):
159
+ self.get_response = get_response
160
+
161
+ def __call__(self, request):
162
+ if request.user.is_authenticated:
163
+ if tzname := request.user.get_config("timezone"):
164
+ timezone.activate(ZoneInfo(tzname))
165
+ else:
166
+ timezone.deactivate()
167
+ return self.get_response(request)
@@ -270,7 +270,7 @@ class BaseModel(models.Model):
270
270
 
271
271
  if not natural_key_field_names:
272
272
  raise AttributeError(
273
- f"Unable to identify an intrinsic natural-key definition for {cls.__name__}. " # pylint: disable=no-member
273
+ f"Unable to identify an intrinsic natural-key definition for {cls.__name__}. "
274
274
  "If there isn't at least one UniqueConstraint, unique_together, or field with unique=True, "
275
275
  "you probably need to explicitly declare the 'natural_key_field_names' for this model, "
276
276
  "or potentially override the default 'natural_key_field_lookups' implementation for this model."
@@ -280,6 +280,8 @@ class JSONArrayField(models.JSONField):
280
280
  """
281
281
  An ArrayField implementation backed JSON storage.
282
282
  Replicates ArrayField's base field validation.
283
+
284
+ Supports choices in the base field.
283
285
  """
284
286
 
285
287
  _default_hint = ("list", "[]")
@@ -375,13 +377,15 @@ class JSONArrayField(models.JSONField):
375
377
 
376
378
  def formfield(self, **kwargs):
377
379
  """Return a django.forms.Field instance for this field."""
378
- return super().formfield(
379
- **{
380
- "form_class": fields.JSONArrayFormField,
381
- "base_field": self.base_field.formfield(),
382
- **kwargs,
383
- }
384
- )
380
+ defaults = {
381
+ "form_class": fields.JSONArrayFormField,
382
+ "base_field": self.base_field.formfield(),
383
+ }
384
+ # If the base field has choices, pass them to the form field.
385
+ if self.base_field.choices:
386
+ defaults["choices"] = self.base_field.choices
387
+ defaults.update(**kwargs)
388
+ return super().formfield(**defaults)
385
389
 
386
390
 
387
391
  class LaxURLField(models.URLField):
@@ -69,7 +69,7 @@ class JSONSet(Func):
69
69
  }
70
70
  return c
71
71
 
72
- def as_sql(self, compiler, connection, function=None, **extra_context): # pylint:disable=arguments-differ
72
+ def as_sql(self, compiler, connection, function=None, **extra_context):
73
73
  """
74
74
  MySQL implementation based on https://github.com/django/django/pull/18489/files.
75
75
 
@@ -138,7 +138,7 @@ class JSONRemove(Func):
138
138
  self.path = path
139
139
  super().__init__(expression)
140
140
 
141
- def as_sql(self, compiler, connection, function=None, **extra_context): # pylint:disable=arguments-differ
141
+ def as_sql(self, compiler, connection, function=None, **extra_context):
142
142
  """
143
143
  MySQL implementation based on https://github.com/django/django/pull/18489/files.
144
144
 
@@ -111,15 +111,12 @@ class TreeModel(TreeNode):
111
111
  if display_str:
112
112
  return display_str
113
113
  try:
114
- if self.parent_id is not None:
115
- parent_display_str = cache.get(cache_key.replace(str(self.id), str(self.parent_id)), "")
116
- if not parent_display_str:
117
- parent_display_str = self.parent.display # pylint: disable=no-member
118
- display_str = parent_display_str + " → "
114
+ if self.parent is not None:
115
+ display_str = self.parent.display + ""
119
116
  except self.DoesNotExist:
120
117
  # Expected to occur at times during bulk-delete operations
121
118
  pass
122
- display_str += self.name # pylint: disable=no-member # we checked with hasattr() above
119
+ display_str += self.name
123
120
  cache.set(cache_key, display_str, 5)
124
121
  return display_str
125
122
 
nautobot/core/settings.py CHANGED
@@ -10,7 +10,11 @@ import django.forms
10
10
  from django.utils.safestring import mark_safe
11
11
 
12
12
  from nautobot import __version__
13
- from nautobot.core.constants import CONFIG_SETTING_SEPARATOR as _CONFIG_SETTING_SEPARATOR
13
+ from nautobot.core.constants import (
14
+ CONFIG_SETTING_SEPARATOR as _CONFIG_SETTING_SEPARATOR,
15
+ MAX_PAGE_SIZE_DEFAULT as _MAX_PAGE_SIZE_DEFAULT,
16
+ PAGINATE_COUNT_DEFAULT as _PAGINATE_COUNT_DEFAULT,
17
+ )
14
18
  from nautobot.core.settings_funcs import ConstanceConfigItem, is_truthy, parse_redis_connection
15
19
 
16
20
  #
@@ -96,6 +100,9 @@ if "NAUTOBOT_DEPLOYMENT_ID" in os.environ and os.environ["NAUTOBOT_DEPLOYMENT_ID
96
100
  if "NAUTOBOT_DEVICE_NAME_AS_NATURAL_KEY" in os.environ and os.environ["NAUTOBOT_DEVICE_NAME_AS_NATURAL_KEY"] != "":
97
101
  DEVICE_NAME_AS_NATURAL_KEY = is_truthy(os.environ["NAUTOBOT_DEVICE_NAME_AS_NATURAL_KEY"])
98
102
 
103
+ # Event Brokers
104
+ EVENT_BROKERS = {}
105
+
99
106
  # Exclude potentially sensitive models from wildcard view exemption. These may still be exempted
100
107
  # by specifying the model individually in the EXEMPT_VIEW_PERMISSIONS configuration parameter.
101
108
  EXEMPT_EXCLUDE_MODELS = (
@@ -173,9 +180,6 @@ PLUGINS_CONFIG = {}
173
180
  if "NAUTOBOT_PREFER_IPV4" in os.environ and os.environ["NAUTOBOT_PREFER_IPV4"] != "":
174
181
  PREFER_IPV4 = is_truthy(os.environ["NAUTOBOT_PREFER_IPV4"])
175
182
 
176
- # Publish a simple "no-index" robots.txt for Nautobot?
177
- PUBLISH_ROBOTS_TXT = is_truthy(os.getenv("NAUTOBOT_PUBLISH_ROBOTS_TXT", "True"))
178
-
179
183
  # Default height and width in pixels of a single rack unit in rendered rack elevations. Defaults are 22 and 220
180
184
  if (
181
185
  "NAUTOBOT_RACK_ELEVATION_DEFAULT_UNIT_HEIGHT" in os.environ
@@ -228,7 +232,7 @@ if SSO_ENABLE_GROUP_SYNC:
228
232
  "social_core.pipeline.social_auth.associate_user",
229
233
  "social_core.pipeline.social_auth.load_extra_data",
230
234
  "social_core.pipeline.user.user_details",
231
- "nautobot.extras.group_sync.group_sync",
235
+ "nautobot.extras.group_sync",
232
236
  )
233
237
  # OAuth2/OIDC claim where the list of groups the authenticating user is a part of
234
238
  SSO_CLAIMS_GROUP = os.getenv("NAUTOBOT_SSO_CLAIMS_GROUP", "groups")
@@ -404,6 +408,11 @@ SPECTACULAR_SETTINGS = {
404
408
  # enum naming encountered a non-optimally resolvable collision for fields named "protocol".
405
409
  "InterfaceRedundancyGroupProtocolChoices": "nautobot.dcim.choices.InterfaceRedundancyGroupProtocolChoices",
406
410
  "ServiceProtocolChoices": "nautobot.ipam.choices.ServiceProtocolChoices",
411
+ # These choice enums need to be overridden because they get assigned to the `mode` field and
412
+ # result in this error:
413
+ # enum naming encountered a non-optimally resolvable collision for fields named "mode".
414
+ "InterfaceModeChoices": "nautobot.dcim.choices.InterfaceModeChoices",
415
+ "WirelessNetworkModeChoices": "nautobot.wireless.choices.WirelessNetworkModeChoices",
407
416
  },
408
417
  # Create separate schema components for PATCH requests (fields generally are not `required` on PATCH)
409
418
  "COMPONENT_SPLIT_PATCH": True,
@@ -553,6 +562,7 @@ INSTALLED_APPS = [
553
562
  "nautobot.tenancy",
554
563
  "nautobot.users",
555
564
  "nautobot.virtualization",
565
+ "nautobot.wireless",
556
566
  "drf_spectacular",
557
567
  "drf_spectacular_sidecar",
558
568
  "graphene_django",
@@ -583,6 +593,7 @@ MIDDLEWARE = [
583
593
  "nautobot.core.middleware.RemoteUserMiddleware",
584
594
  "nautobot.core.middleware.ExternalAuthMiddleware",
585
595
  "nautobot.core.middleware.ObjectChangeMiddleware",
596
+ "nautobot.core.middleware.UserDefinedTimeZoneMiddleware",
586
597
  "django_prometheus.middleware.PrometheusAfterMiddleware",
587
598
  ]
588
599
 
@@ -761,13 +772,13 @@ CONSTANCE_CONFIG = {
761
772
  field_type=bool,
762
773
  ),
763
774
  "MAX_PAGE_SIZE": ConstanceConfigItem(
764
- default=1000,
775
+ default=_MAX_PAGE_SIZE_DEFAULT,
765
776
  help_text="Maximum number of objects that a user can list in one UI page or one API call.\n"
766
777
  "If set to 0, a user can retrieve an unlimited number of objects.",
767
778
  field_type=int,
768
779
  ),
769
780
  "PAGINATE_COUNT": ConstanceConfigItem(
770
- default=50,
781
+ default=_PAGINATE_COUNT_DEFAULT,
771
782
  help_text="Default number of objects to display per page when listing objects in the UI and/or REST API.",
772
783
  field_type=int,
773
784
  ),
@@ -1113,3 +1124,29 @@ def silk_request_logging_intercept_logic(request):
1113
1124
 
1114
1125
 
1115
1126
  SILKY_INTERCEPT_FUNC = silk_request_logging_intercept_logic
1127
+
1128
+ #
1129
+ # Kubernetes settings variables
1130
+ #
1131
+
1132
+ # Host of the kubernetes pod created in the kubernetes cluster
1133
+ KUBERNETES_DEFAULT_SERVICE_ADDRESS = os.getenv("NAUTOBOT_KUBERNETES_DEFAULT_SERVICE_ADDRESS", "")
1134
+
1135
+ # A dictionary that stores the kubernetes pod manifest used to create a job pod in the kubernetes cluster
1136
+ KUBERNETES_JOB_MANIFEST = {}
1137
+
1138
+ # Name of the kubernetes pod created in the kubernetes cluster
1139
+ KUBERNETES_JOB_POD_NAME = os.getenv("NAUTOBOT_KUBERNETES_JOB_POD_NAME", "")
1140
+
1141
+ # Namespace of the kubernetes pod created in the kubernetes cluster
1142
+ KUBERNETES_JOB_POD_NAMESPACE = os.getenv("NAUTOBOT_KUBERNETES_JOB_POD_NAMESPACE", "")
1143
+
1144
+ # File path to the SSL CA CERT used for authentication to create the job and job pod
1145
+ KUBERNETES_SSL_CA_CERT_PATH = os.getenv(
1146
+ "NAUTOBOT_KUBERNETES_SSL_CA_CERT_PATH", "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
1147
+ )
1148
+
1149
+ # File path to the Bearer token used for authentication to create the job and job pod
1150
+ KUBERNETES_TOKEN_PATH = os.getenv(
1151
+ "NAUTOBOT_KUBERNETES_TOKEN_PATH", "/var/run/secrets/kubernetes.io/serviceaccount/token"
1152
+ )
@@ -766,6 +766,57 @@ properties:
766
766
  is_constance_config: true
767
767
  type: "boolean"
768
768
  version_added: "2.0.0"
769
+ EVENT_BROKERS:
770
+ default: {}
771
+ description: >-
772
+ A dictionary defining event brokers that handle event publishing in Nautobot.
773
+ Each broker specifies its import path, along with topics to include or exclude
774
+ when publishing events.
775
+ details: |-
776
+ Each broker consists of a name, the class it uses for publishing events, and the topics
777
+ it filters. Topics are the categories of events that a broker will publish or exclude
778
+ based on the provided filters.
779
+
780
+ Example:
781
+
782
+ ```python
783
+ EVENT_BROKERS = {
784
+ "SyslogEventBroker": {
785
+ "CLASS": "nautobot.core.events.SyslogEventBroker",
786
+ "TOPICS": {
787
+ "INCLUDE": ["nautobot.test.*"],
788
+ "EXCLUDE": ["*.no-publish*"],
789
+ },
790
+ },
791
+ }
792
+ ```
793
+
794
+ In this example:
795
+ - **SyslogEventBroker** is the broker name.
796
+ - **CLASS** specifies the path to the event broker's Python class.
797
+ - **INCLUDE** filters the events the broker will publish, such as all topics starting with "nautobot.test."
798
+ - **EXCLUDE** filters out specific topics like those with "no-publish" in the name.
799
+
800
+ !!! note
801
+ If **INCLUDE** is set to ["*"], all topics will be published unless excluded by **EXCLUDE**.
802
+ properties:
803
+ CLASS:
804
+ type: "string"
805
+ TOPICS:
806
+ type: "object"
807
+ properties:
808
+ INCLUDE:
809
+ type: "array"
810
+ description: >-
811
+ List of topics that the broker should publish events for.
812
+ If empty or set to ["*"], all topics will be included.
813
+ EXCLUDE:
814
+ type: "array"
815
+ description: >-
816
+ List of topics that the broker should exclude from publishing.
817
+ If empty, no topics are excluded.
818
+ type: "object"
819
+ version_added: "2.4.0"
769
820
  EXEMPT_VIEW_PERMISSIONS:
770
821
  default: []
771
822
  description: "A list of Nautobot models to exempt from the enforcement of view permissions."
@@ -1007,6 +1058,41 @@ properties:
1007
1058
  +/- 2.0.0
1008
1059
  This directory no longer requires an `__init__.py` file.
1009
1060
  environment_variable: "NAUTOBOT_JOBS_ROOT"
1061
+ KUBERNETES_DEFAULT_SERVICE_ADDRESS:
1062
+ default: ""
1063
+ description: "HTTP address of the Kubernetes cluster. e.g. https://kubernetes.default.svc"
1064
+ environment_variable: "NAUTOBOT_KUBERNETES_DEFAULT_SERVICE_ADDRESS"
1065
+ type: "string"
1066
+ version_added: "2.4.0"
1067
+ KUBERNETES_JOB_MANIFEST:
1068
+ default: {}
1069
+ description: "A dictionary that contains the pod manifest used to create a job pod in the kubernetes cluster."
1070
+ type: "object"
1071
+ version_added: "2.4.0"
1072
+ KUBERNETES_JOB_POD_NAME:
1073
+ default: ""
1074
+ description: "Name of the Kubernetes pod."
1075
+ environment_variable: "NAUTOBOT_KUBERNETES_JOB_POD_NAME"
1076
+ type: "string"
1077
+ version_added: "2.4.0"
1078
+ KUBERNETES_JOB_POD_NAMESPACE:
1079
+ default: ""
1080
+ description: "Name of the namespace that the Kubernetes pod is created in."
1081
+ environment_variable: "NAUTOBOT_KUBERNETES_JOB_POD_NAMESPACE"
1082
+ type: "string"
1083
+ version_added: "2.4.0"
1084
+ KUBERNETES_SSL_CA_CERT_PATH:
1085
+ default: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
1086
+ description: "File path to the SSL CA CERT used for authentication to create the job and job pod."
1087
+ environment_variable: "NAUTOBOT_KUBERNETES_SSL_CA_CERT_PATH"
1088
+ type: "string"
1089
+ version_added: "2.4.0"
1090
+ KUBERNETES_TOKEN_PATH:
1091
+ default: "/var/run/secrets/kubernetes.io/serviceaccount/token"
1092
+ description: "File path to the Bearer token used for authentication to create the job and job pod."
1093
+ environment_variable: "NAUTOBOT_KUBERNETES_TOKEN_PATH"
1094
+ type: "string"
1095
+ version_added: "2.4.0"
1010
1096
  LOCATION_NAME_AS_NATURAL_KEY:
1011
1097
  default: false
1012
1098
  description: >-
@@ -1473,14 +1559,6 @@ properties:
1473
1559
  environment_variable: "NAUTOBOT_PREFER_IPV4"
1474
1560
  is_constance_config: true
1475
1561
  type: "boolean"
1476
- PUBLISH_ROBOTS_TXT:
1477
- default: true
1478
- description: >-
1479
- Setting this to true causes Nautobot to publish a `robots.txt` that discourages indexing by web crawlers.
1480
- Irrelevant if deployed behind a firewall.
1481
- environment_variable: "NAUTOBOT_PUBLISH_ROBOTS_TXT"
1482
- type: "boolean"
1483
- version_added: "2.3.15"
1484
1562
  RACK_ELEVATION_DEFAULT_UNIT_HEIGHT:
1485
1563
  default: 22
1486
1564
  description: >-