nautobot 2.4.0b1__py3-none-any.whl → 2.4.1__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 (601) hide show
  1. nautobot/apps/__init__.py +1 -1
  2. nautobot/apps/api.py +8 -8
  3. nautobot/apps/change_logging.py +2 -2
  4. nautobot/apps/choices.py +4 -4
  5. nautobot/apps/events.py +3 -3
  6. nautobot/apps/factory.py +2 -2
  7. nautobot/apps/filters.py +1 -1
  8. nautobot/apps/forms.py +20 -20
  9. nautobot/apps/graphql.py +2 -2
  10. nautobot/apps/jobs.py +8 -8
  11. nautobot/apps/models.py +19 -19
  12. nautobot/apps/tables.py +1 -1
  13. nautobot/apps/testing.py +10 -10
  14. nautobot/apps/ui.py +2 -2
  15. nautobot/apps/utils.py +7 -7
  16. nautobot/apps/views.py +7 -7
  17. nautobot/circuits/api/serializers.py +1 -0
  18. nautobot/circuits/api/views.py +4 -8
  19. nautobot/circuits/tables.py +2 -1
  20. nautobot/circuits/templates/circuits/circuit_create.html +1 -7
  21. nautobot/circuits/views.py +3 -3
  22. nautobot/cloud/api/views.py +6 -10
  23. nautobot/cloud/models.py +1 -1
  24. nautobot/cloud/views.py +0 -16
  25. nautobot/core/api/constants.py +11 -0
  26. nautobot/core/api/fields.py +5 -5
  27. nautobot/core/api/filter_backends.py +3 -9
  28. nautobot/core/api/schema.py +13 -2
  29. nautobot/core/api/serializers.py +40 -34
  30. nautobot/core/api/views.py +56 -4
  31. nautobot/core/celery/log.py +4 -4
  32. nautobot/core/celery/schedulers.py +2 -2
  33. nautobot/core/choices.py +2 -2
  34. nautobot/core/events/__init__.py +3 -3
  35. nautobot/core/filters.py +67 -35
  36. nautobot/core/forms/__init__.py +19 -19
  37. nautobot/core/forms/fields.py +14 -11
  38. nautobot/core/forms/forms.py +33 -2
  39. nautobot/core/graphql/types.py +1 -1
  40. nautobot/core/jobs/__init__.py +28 -7
  41. nautobot/core/jobs/bulk_actions.py +285 -0
  42. nautobot/core/jobs/cleanup.py +48 -12
  43. nautobot/core/jobs/groups.py +1 -1
  44. nautobot/core/management/commands/validate_models.py +1 -1
  45. nautobot/core/models/__init__.py +3 -1
  46. nautobot/core/models/query_functions.py +2 -2
  47. nautobot/core/models/tree_queries.py +6 -3
  48. nautobot/core/settings.py +29 -2
  49. nautobot/core/settings.yaml +21 -0
  50. nautobot/core/tables.py +79 -61
  51. nautobot/core/templates/about.html +67 -0
  52. nautobot/core/templates/inc/media.html +3 -0
  53. nautobot/core/templates/inc/nav_menu.html +1 -0
  54. nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
  55. nautobot/core/templates/inc/tenant_table_row.html +11 -0
  56. nautobot/core/templates/nautobot_config.py.j2 +13 -0
  57. nautobot/core/templates/search.html +7 -0
  58. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  59. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  60. nautobot/core/templates/utilities/theme_preview.html +7 -0
  61. nautobot/core/templatetags/helpers.py +11 -2
  62. nautobot/core/testing/__init__.py +8 -8
  63. nautobot/core/testing/api.py +170 -15
  64. nautobot/core/testing/filters.py +45 -10
  65. nautobot/core/testing/forms.py +2 -0
  66. nautobot/core/testing/integration.py +86 -4
  67. nautobot/core/testing/mixins.py +7 -2
  68. nautobot/core/testing/views.py +44 -29
  69. nautobot/core/tests/integration/test_app_home.py +0 -1
  70. nautobot/core/tests/integration/test_app_navbar.py +0 -1
  71. nautobot/core/tests/integration/test_filters.py +0 -2
  72. nautobot/core/tests/integration/test_home.py +0 -1
  73. nautobot/core/tests/integration/test_navbar.py +0 -1
  74. nautobot/core/tests/integration/test_view_authentication.py +1 -0
  75. nautobot/core/tests/runner.py +1 -1
  76. nautobot/core/tests/test_api.py +98 -1
  77. nautobot/core/tests/test_csv.py +25 -3
  78. nautobot/core/tests/test_filters.py +209 -246
  79. nautobot/core/tests/test_forms.py +1 -0
  80. nautobot/core/tests/test_jobs.py +460 -1
  81. nautobot/core/tests/test_models.py +9 -0
  82. nautobot/core/tests/test_settings_schema.py +7 -0
  83. nautobot/core/tests/test_tables.py +100 -0
  84. nautobot/core/tests/test_utils.py +63 -1
  85. nautobot/core/tests/test_views.py +30 -3
  86. nautobot/core/ui/nav.py +1 -0
  87. nautobot/core/ui/object_detail.py +15 -1
  88. nautobot/core/urls.py +11 -0
  89. nautobot/core/utils/lookup.py +11 -8
  90. nautobot/core/utils/querysets.py +64 -0
  91. nautobot/core/utils/requests.py +24 -9
  92. nautobot/core/views/__init__.py +42 -0
  93. nautobot/core/views/generic.py +131 -197
  94. nautobot/core/views/mixins.py +126 -38
  95. nautobot/core/views/renderers.py +6 -6
  96. nautobot/dcim/api/serializers.py +56 -64
  97. nautobot/dcim/api/views.py +47 -113
  98. nautobot/dcim/constants.py +6 -13
  99. nautobot/dcim/factory.py +6 -1
  100. nautobot/dcim/filters/__init__.py +31 -2
  101. nautobot/dcim/forms.py +36 -17
  102. nautobot/dcim/graphql/types.py +2 -2
  103. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
  104. nautobot/dcim/models/__init__.py +1 -1
  105. nautobot/dcim/models/device_component_templates.py +2 -2
  106. nautobot/dcim/models/device_components.py +22 -20
  107. nautobot/dcim/models/devices.py +10 -1
  108. nautobot/dcim/models/locations.py +3 -3
  109. nautobot/dcim/models/power.py +6 -5
  110. nautobot/dcim/models/racks.py +4 -4
  111. nautobot/dcim/tables/__init__.py +3 -3
  112. nautobot/dcim/tables/devices.py +7 -5
  113. nautobot/dcim/tables/devicetypes.py +2 -2
  114. nautobot/dcim/tables/racks.py +1 -1
  115. nautobot/dcim/templates/dcim/controller_create.html +1 -7
  116. nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
  117. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
  118. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
  119. nautobot/dcim/templates/dcim/device.html +1 -9
  120. nautobot/dcim/templates/dcim/device_edit.html +36 -37
  121. nautobot/dcim/templates/dcim/location.html +1 -9
  122. nautobot/dcim/templates/dcim/location_edit.html +1 -7
  123. nautobot/dcim/templates/dcim/rack.html +1 -9
  124. nautobot/dcim/templates/dcim/rack_edit.html +1 -7
  125. nautobot/dcim/templates/dcim/rackreservation.html +1 -9
  126. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
  127. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
  128. nautobot/dcim/tests/integration/test_controller.py +62 -0
  129. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
  130. nautobot/dcim/tests/integration/test_device_bulk_delete.py +189 -0
  131. nautobot/dcim/tests/integration/test_device_bulk_edit.py +181 -0
  132. nautobot/dcim/tests/test_api.py +16 -5
  133. nautobot/dcim/tests/test_filters.py +33 -0
  134. nautobot/dcim/tests/test_forms.py +51 -2
  135. nautobot/dcim/tests/test_graphql.py +52 -0
  136. nautobot/dcim/tests/test_jobs.py +118 -0
  137. nautobot/dcim/tests/test_models.py +52 -9
  138. nautobot/dcim/tests/test_views.py +21 -83
  139. nautobot/dcim/views.py +1 -13
  140. nautobot/extras/api/customfields.py +2 -2
  141. nautobot/extras/api/serializers.py +90 -85
  142. nautobot/extras/api/views.py +22 -27
  143. nautobot/extras/constants.py +2 -0
  144. nautobot/extras/filters/__init__.py +8 -6
  145. nautobot/extras/forms/base.py +2 -2
  146. nautobot/extras/forms/forms.py +139 -31
  147. nautobot/extras/forms/mixins.py +14 -6
  148. nautobot/extras/group_sync.py +3 -3
  149. nautobot/extras/health_checks.py +1 -2
  150. nautobot/extras/jobs.py +85 -18
  151. nautobot/extras/managers.py +3 -1
  152. nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
  153. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
  154. nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
  155. nautobot/extras/models/__init__.py +1 -1
  156. nautobot/extras/models/contacts.py +1 -1
  157. nautobot/extras/models/customfields.py +12 -11
  158. nautobot/extras/models/groups.py +11 -9
  159. nautobot/extras/models/jobs.py +23 -4
  160. nautobot/extras/models/models.py +2 -2
  161. nautobot/extras/plugins/__init__.py +13 -2
  162. nautobot/extras/plugins/marketplace_manifest.yml +84 -79
  163. nautobot/extras/plugins/tables.py +16 -14
  164. nautobot/extras/plugins/views.py +65 -69
  165. nautobot/extras/registry.py +1 -1
  166. nautobot/extras/secrets/__init__.py +2 -2
  167. nautobot/extras/tables.py +7 -5
  168. nautobot/extras/templates/extras/dynamicgroup.html +1 -9
  169. nautobot/extras/templates/extras/job_detail.html +16 -0
  170. nautobot/extras/templates/extras/job_edit.html +1 -0
  171. nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
  172. nautobot/extras/templates/extras/marketplace.html +29 -11
  173. nautobot/extras/templates/extras/plugin_detail.html +32 -15
  174. nautobot/extras/templates/extras/plugins_tiles.html +21 -10
  175. nautobot/extras/templatetags/job_buttons.py +4 -4
  176. nautobot/extras/test_jobs/api_test_job.py +1 -1
  177. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  178. nautobot/extras/test_jobs/dry_run.py +1 -1
  179. nautobot/extras/test_jobs/fail.py +5 -5
  180. nautobot/extras/test_jobs/file_output.py +1 -1
  181. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  182. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  183. nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
  184. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  185. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  186. nautobot/extras/test_jobs/log_redaction.py +1 -1
  187. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  188. nautobot/extras/test_jobs/modify_db.py +1 -1
  189. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  190. nautobot/extras/test_jobs/object_var_required.py +1 -1
  191. nautobot/extras/test_jobs/object_vars.py +1 -1
  192. nautobot/extras/test_jobs/pass.py +3 -3
  193. nautobot/extras/test_jobs/profiling.py +1 -1
  194. nautobot/extras/test_jobs/relative_import.py +3 -3
  195. nautobot/extras/test_jobs/singleton.py +16 -0
  196. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  197. nautobot/extras/test_jobs/task_queues.py +1 -1
  198. nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
  199. nautobot/extras/tests/test_api.py +13 -13
  200. nautobot/extras/tests/test_customfields.py +1 -1
  201. nautobot/extras/tests/test_datasources.py +2 -1
  202. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  203. nautobot/extras/tests/test_filters.py +6 -6
  204. nautobot/extras/tests/test_forms.py +33 -1
  205. nautobot/extras/tests/test_jobs.py +178 -32
  206. nautobot/extras/tests/test_models.py +16 -10
  207. nautobot/extras/tests/test_plugins.py +62 -9
  208. nautobot/extras/tests/test_relationships.py +120 -9
  209. nautobot/extras/tests/test_views.py +56 -194
  210. nautobot/extras/utils.py +3 -2
  211. nautobot/extras/views.py +30 -98
  212. nautobot/ipam/api/fields.py +3 -3
  213. nautobot/ipam/api/serializers.py +41 -33
  214. nautobot/ipam/api/views.py +68 -117
  215. nautobot/ipam/factory.py +1 -1
  216. nautobot/ipam/filters.py +3 -2
  217. nautobot/ipam/lookups.py +101 -62
  218. nautobot/ipam/models.py +66 -16
  219. nautobot/ipam/querysets.py +2 -2
  220. nautobot/ipam/tables.py +23 -7
  221. nautobot/ipam/templates/ipam/ipaddress.html +1 -9
  222. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
  223. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
  224. nautobot/ipam/templates/ipam/prefix.html +1 -9
  225. nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
  226. nautobot/ipam/templates/ipam/vlan.html +1 -9
  227. nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
  228. nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
  229. nautobot/ipam/tests/test_api.py +436 -3
  230. nautobot/ipam/tests/test_forms.py +49 -47
  231. nautobot/ipam/tests/test_migrations.py +30 -30
  232. nautobot/ipam/tests/test_models.py +95 -34
  233. nautobot/ipam/tests/test_querysets.py +63 -1
  234. nautobot/ipam/tests/test_views.py +3 -0
  235. nautobot/ipam/utils/__init__.py +36 -6
  236. nautobot/ipam/views.py +61 -87
  237. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  238. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  239. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
  240. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  241. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  242. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  243. nautobot/project-static/docs/404.html +46 -4
  244. nautobot/project-static/docs/apps/index.html +46 -4
  245. nautobot/project-static/docs/apps/nautobot-apps.html +47 -6
  246. nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
  247. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
  248. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
  249. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +62 -10
  250. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +59 -7
  251. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +374 -122
  252. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +90 -18
  253. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +95 -21
  254. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +53 -6
  255. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +52 -5
  256. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +79 -17
  257. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +102 -28
  258. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +108 -21
  259. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +131 -38
  260. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +239 -65
  261. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +581 -165
  262. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +109 -36
  263. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +453 -167
  264. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +493 -211
  265. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +60 -8
  266. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +71 -15
  267. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +407 -55
  268. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +620 -205
  269. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +858 -412
  270. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +59 -7
  271. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +448 -186
  272. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +365 -147
  273. nautobot/project-static/docs/development/apps/api/configuration-view.html +46 -4
  274. nautobot/project-static/docs/development/apps/api/database-backend-config.html +46 -4
  275. nautobot/project-static/docs/development/apps/api/models/django-admin.html +46 -4
  276. nautobot/project-static/docs/development/apps/api/models/global-search.html +46 -4
  277. nautobot/project-static/docs/development/apps/api/models/graphql.html +46 -4
  278. nautobot/project-static/docs/development/apps/api/models/index.html +46 -4
  279. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +46 -4
  280. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +46 -4
  281. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +46 -4
  282. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +46 -4
  283. nautobot/project-static/docs/development/apps/api/platform-features/index.html +46 -4
  284. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +46 -4
  285. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +46 -4
  286. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +46 -4
  287. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +46 -4
  288. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +68 -7
  289. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +46 -4
  290. nautobot/project-static/docs/development/apps/api/prometheus.html +46 -4
  291. nautobot/project-static/docs/development/apps/api/setup.html +46 -4
  292. nautobot/project-static/docs/development/apps/api/testing.html +46 -4
  293. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +46 -4
  294. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +46 -4
  295. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +46 -4
  296. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +46 -4
  297. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +46 -4
  298. nautobot/project-static/docs/development/apps/api/views/base-template.html +46 -4
  299. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +46 -4
  300. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +46 -4
  301. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +46 -4
  302. nautobot/project-static/docs/development/apps/api/views/index.html +46 -4
  303. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +46 -4
  304. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +46 -4
  305. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +46 -4
  306. nautobot/project-static/docs/development/apps/api/views/notes.html +46 -4
  307. nautobot/project-static/docs/development/apps/api/views/rest-api.html +52 -6
  308. nautobot/project-static/docs/development/apps/api/views/urls.html +46 -4
  309. nautobot/project-static/docs/development/apps/index.html +46 -4
  310. nautobot/project-static/docs/development/apps/migration/code-updates.html +46 -4
  311. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +46 -4
  312. nautobot/project-static/docs/development/apps/migration/from-v1.html +46 -4
  313. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +46 -4
  314. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +46 -4
  315. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +46 -4
  316. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +46 -4
  317. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +50 -8
  318. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +46 -4
  319. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +211 -14
  320. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +46 -4
  321. nautobot/project-static/docs/development/apps/porting-from-netbox.html +46 -4
  322. nautobot/project-static/docs/development/core/application-registry.html +46 -4
  323. nautobot/project-static/docs/development/core/best-practices.html +46 -4
  324. nautobot/project-static/docs/development/core/bootstrap-ui.html +46 -4
  325. nautobot/project-static/docs/development/core/caching.html +46 -4
  326. nautobot/project-static/docs/development/core/controllers.html +46 -4
  327. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +73 -74
  328. nautobot/project-static/docs/development/core/generic-views.html +46 -4
  329. nautobot/project-static/docs/development/core/getting-started.html +249 -224
  330. nautobot/project-static/docs/development/core/homepage.html +49 -7
  331. nautobot/project-static/docs/development/core/index.html +46 -4
  332. nautobot/project-static/docs/development/core/{local-k8s.html → minikube-dev-environment-for-k8s-jobs.html} +469 -168
  333. nautobot/project-static/docs/development/core/model-checklist.html +56 -12
  334. nautobot/project-static/docs/development/core/model-features.html +46 -4
  335. nautobot/project-static/docs/development/core/natural-keys.html +46 -4
  336. nautobot/project-static/docs/development/core/navigation-menu.html +46 -4
  337. nautobot/project-static/docs/development/core/release-checklist.html +49 -7
  338. nautobot/project-static/docs/development/core/role-internals.html +46 -4
  339. nautobot/project-static/docs/development/core/settings.html +46 -4
  340. nautobot/project-static/docs/development/core/style-guide.html +49 -7
  341. nautobot/project-static/docs/development/core/templates.html +46 -4
  342. nautobot/project-static/docs/development/core/testing.html +46 -4
  343. nautobot/project-static/docs/development/core/ui-component-framework.html +369 -273
  344. nautobot/project-static/docs/development/core/user-preferences.html +46 -4
  345. nautobot/project-static/docs/development/index.html +46 -4
  346. nautobot/project-static/docs/development/jobs/index.html +216 -122
  347. nautobot/project-static/docs/development/jobs/migration/from-v1.html +46 -4
  348. nautobot/project-static/docs/index.html +54 -23
  349. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  350. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  351. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  352. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  353. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  354. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  355. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  356. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  357. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  358. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  359. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  360. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  361. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  362. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  363. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  364. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  365. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  366. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  367. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  368. nautobot/project-static/docs/objects.inv +0 -0
  369. nautobot/project-static/docs/overview/application_stack.html +47 -7
  370. nautobot/project-static/docs/overview/design_philosophy.html +46 -4
  371. nautobot/project-static/docs/release-notes/index.html +52 -12
  372. nautobot/project-static/docs/release-notes/version-1.0.html +234 -193
  373. nautobot/project-static/docs/release-notes/version-1.1.html +231 -190
  374. nautobot/project-static/docs/release-notes/version-1.2.html +306 -265
  375. nautobot/project-static/docs/release-notes/version-1.3.html +332 -291
  376. nautobot/project-static/docs/release-notes/version-1.4.html +417 -377
  377. nautobot/project-static/docs/release-notes/version-1.5.html +605 -566
  378. nautobot/project-static/docs/release-notes/version-1.6.html +904 -447
  379. nautobot/project-static/docs/release-notes/version-2.0.html +528 -489
  380. nautobot/project-static/docs/release-notes/version-2.1.html +363 -324
  381. nautobot/project-static/docs/release-notes/version-2.2.html +356 -317
  382. nautobot/project-static/docs/release-notes/version-2.3.html +997 -352
  383. nautobot/project-static/docs/release-notes/version-2.4.html +525 -101
  384. nautobot/project-static/docs/requirements.txt +2 -2
  385. nautobot/project-static/docs/search/search_index.json +1 -1
  386. nautobot/project-static/docs/sitemap.xml +295 -287
  387. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  388. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +46 -4
  389. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +46 -4
  390. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +48 -6
  391. nautobot/project-static/docs/user-guide/administration/configuration/index.html +46 -4
  392. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +46 -4
  393. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +110 -8
  394. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +46 -4
  395. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +46 -4
  396. nautobot/project-static/docs/user-guide/administration/guides/docker.html +46 -4
  397. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +46 -4
  398. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +46 -4
  399. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +46 -4
  400. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +46 -4
  401. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +46 -4
  402. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +48 -6
  403. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +46 -4
  404. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +46 -4
  405. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +46 -4
  406. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +66 -8
  407. nautobot/project-static/docs/user-guide/administration/installation/index.html +46 -4
  408. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +47 -5
  409. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +46 -4
  410. nautobot/project-static/docs/user-guide/administration/installation/services.html +46 -4
  411. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +46 -4
  412. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +46 -4
  413. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +46 -4
  414. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +46 -4
  415. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +46 -4
  416. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +46 -4
  417. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +46 -4
  418. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +46 -4
  419. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +46 -4
  420. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +49 -8
  421. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +46 -4
  422. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +46 -4
  423. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +46 -4
  424. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +46 -4
  425. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +46 -4
  426. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +46 -4
  427. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +46 -4
  428. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +46 -4
  429. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +46 -4
  430. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +46 -4
  431. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +46 -4
  432. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +46 -4
  433. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +46 -4
  434. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +46 -4
  435. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +46 -4
  436. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +46 -4
  437. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +46 -4
  438. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +46 -4
  439. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +46 -4
  440. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +46 -4
  441. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +46 -4
  442. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +46 -4
  443. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +46 -4
  444. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +46 -4
  445. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +46 -4
  446. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +46 -4
  447. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +46 -4
  448. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +46 -4
  449. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +46 -4
  450. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +46 -4
  451. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +46 -4
  452. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +46 -4
  453. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +46 -4
  454. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +46 -4
  455. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +46 -4
  456. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +46 -4
  457. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +46 -4
  458. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +46 -4
  459. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +46 -4
  460. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +46 -4
  461. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +46 -4
  462. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +46 -4
  463. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +46 -4
  464. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +46 -4
  465. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +46 -4
  466. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +46 -4
  467. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +46 -4
  468. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +46 -4
  469. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +46 -4
  470. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +46 -4
  471. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +46 -4
  472. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +46 -4
  473. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +46 -4
  474. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +46 -4
  475. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +46 -4
  476. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +46 -4
  477. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +46 -4
  478. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +50 -12
  479. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +46 -4
  480. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +46 -4
  481. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +46 -4
  482. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +46 -4
  483. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +46 -4
  484. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +46 -4
  485. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +46 -4
  486. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +46 -4
  487. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +46 -4
  488. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +46 -4
  489. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +46 -4
  490. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +46 -4
  491. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +49 -7
  492. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +46 -4
  493. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +46 -4
  494. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +46 -4
  495. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +46 -4
  496. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +46 -4
  497. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +46 -4
  498. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +46 -4
  499. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +46 -4
  500. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +46 -4
  501. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +46 -4
  502. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +46 -4
  503. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +46 -4
  504. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +46 -4
  505. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +46 -4
  506. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +46 -4
  507. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +46 -4
  508. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +46 -4
  509. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +46 -4
  510. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +46 -4
  511. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +46 -4
  512. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +46 -4
  513. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +46 -4
  514. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +51 -7
  515. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +46 -4
  516. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  517. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  518. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  519. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  520. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  521. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  522. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  523. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  524. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  525. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  526. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  527. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  528. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  529. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +46 -4
  530. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +46 -4
  531. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +49 -7
  532. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
  533. nautobot/project-static/docs/user-guide/index.html +46 -4
  534. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +46 -4
  535. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +50 -8
  536. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +46 -4
  537. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +46 -4
  538. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +46 -4
  539. nautobot/project-static/docs/user-guide/platform-functionality/events.html +46 -4
  540. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +46 -4
  541. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +46 -4
  542. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +46 -4
  543. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +46 -4
  544. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +46 -4
  545. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +46 -4
  546. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +50 -7
  547. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +46 -4
  548. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +49 -7
  549. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +46 -4
  550. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +46 -4
  551. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9722 -0
  552. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +46 -4
  553. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +46 -4
  554. nautobot/project-static/docs/user-guide/platform-functionality/note.html +46 -4
  555. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +46 -4
  556. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +47 -5
  557. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +46 -4
  558. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +46 -4
  559. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +94 -25
  560. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +74 -5
  561. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +46 -4
  562. nautobot/project-static/docs/user-guide/platform-functionality/role.html +46 -4
  563. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +46 -4
  564. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +46 -4
  565. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +46 -4
  566. nautobot/project-static/docs/user-guide/platform-functionality/status.html +46 -4
  567. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +46 -4
  568. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +46 -4
  569. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +46 -4
  570. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +46 -4
  571. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +46 -4
  572. nautobot/project-static/js/forms.js +1 -1
  573. nautobot/tenancy/api/views.py +9 -13
  574. nautobot/tenancy/views.py +4 -2
  575. nautobot/users/admin.py +1 -1
  576. nautobot/users/api/serializers.py +5 -4
  577. nautobot/users/api/views.py +3 -3
  578. nautobot/virtualization/api/serializers.py +4 -4
  579. nautobot/virtualization/api/views.py +5 -24
  580. nautobot/virtualization/filters.py +20 -3
  581. nautobot/virtualization/models.py +1 -1
  582. nautobot/virtualization/tables.py +2 -2
  583. nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
  584. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -9
  585. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
  586. nautobot/virtualization/tests/test_filters.py +17 -0
  587. nautobot/wireless/filters.py +2 -2
  588. nautobot/wireless/forms.py +1 -1
  589. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
  590. nautobot/wireless/tests/integration/__init__.py +0 -0
  591. nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
  592. nautobot/wireless/tests/test_filters.py +29 -1
  593. nautobot/wireless/tests/test_views.py +22 -1
  594. nautobot/wireless/views.py +0 -10
  595. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/METADATA +6 -6
  596. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/RECORD +600 -550
  597. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/WHEEL +1 -1
  598. nautobot/core/fixtures/user-data.json +0 -59
  599. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/LICENSE.txt +0 -0
  600. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/NOTICE +0 -0
  601. {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/entry_points.txt +0 -0
@@ -17,6 +17,7 @@ from rest_framework.permissions import IsAuthenticated
17
17
  from rest_framework.response import Response
18
18
 
19
19
  from nautobot.core.api.authentication import TokenPermissions
20
+ from nautobot.core.api.parsers import NautobotCSVParser
20
21
  from nautobot.core.api.utils import get_serializer_for_model
21
22
  from nautobot.core.api.views import (
22
23
  BulkDestroyModelMixin,
@@ -180,14 +181,7 @@ class ConfigContextQuerySetMixin:
180
181
 
181
182
 
182
183
  class ConfigContextViewSet(NotesViewSetMixin, ModelViewSet):
183
- queryset = ConfigContext.objects.prefetch_related(
184
- "locations",
185
- "roles",
186
- "device_types",
187
- "platforms",
188
- "tenant_groups",
189
- "tenants",
190
- )
184
+ queryset = ConfigContext.objects.all()
191
185
  serializer_class = serializers.ConfigContextSerializer
192
186
  filterset_class = filters.ConfigContextFilterSet
193
187
 
@@ -304,7 +298,7 @@ class DynamicGroupViewSet(NotesViewSetMixin, ModelViewSet):
304
298
  Manage Dynamic Groups through DELETE, GET, POST, PUT, and PATCH requests.
305
299
  """
306
300
 
307
- queryset = DynamicGroup.objects.select_related("content_type")
301
+ queryset = DynamicGroup.objects.all()
308
302
  serializer_class = serializers.DynamicGroupSerializer
309
303
  filterset_class = filters.DynamicGroupFilterSet
310
304
 
@@ -329,7 +323,7 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
329
323
  Manage Dynamic Group Memberships through DELETE, GET, POST, PUT, and PATCH requests.
330
324
  """
331
325
 
332
- queryset = DynamicGroupMembership.objects.select_related("group", "parent_group")
326
+ queryset = DynamicGroupMembership.objects.all()
333
327
  serializer_class = serializers.DynamicGroupMembershipSerializer
334
328
  filterset_class = filters.DynamicGroupMembershipFilterSet
335
329
 
@@ -340,13 +334,13 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
340
334
 
341
335
 
342
336
  class SavedViewViewSet(ModelViewSet):
343
- queryset = SavedView.objects.select_related("owner")
337
+ queryset = SavedView.objects.all()
344
338
  serializer_class = serializers.SavedViewSerializer
345
339
  filterset_class = filters.SavedViewFilterSet
346
340
 
347
341
 
348
342
  class UserSavedViewAssociationViewSet(ModelViewSet):
349
- queryset = UserSavedViewAssociation.objects.select_related("user", "saved_view")
343
+ queryset = UserSavedViewAssociation.objects.all()
350
344
  serializer_class = serializers.UserSavedViewAssociationSerializer
351
345
  filterset_class = filters.UserSavedViewAssociationFilterSet
352
346
 
@@ -356,7 +350,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
356
350
  Manage Static Group Associations through DELETE, GET, POST, PUT, and PATCH requests.
357
351
  """
358
352
 
359
- queryset = StaticGroupAssociation.objects.select_related("associated_object_type", "dynamic_group")
353
+ queryset = StaticGroupAssociation.objects.all()
360
354
  serializer_class = serializers.StaticGroupAssociationSerializer
361
355
  filterset_class = filters.StaticGroupAssociationFilterSet
362
356
 
@@ -367,7 +361,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
367
361
  and "dynamic_group" in self.request.GET
368
362
  and self.action in ["list", "retrieve"]
369
363
  ):
370
- self.queryset = StaticGroupAssociation.all_objects.select_related("associated_object_type", "dynamic_group")
364
+ self.queryset = StaticGroupAssociation.all_objects.all()
371
365
  return super().get_queryset()
372
366
 
373
367
 
@@ -388,7 +382,7 @@ class ExportTemplateViewSet(NotesViewSetMixin, ModelViewSet):
388
382
 
389
383
 
390
384
  class ExternalIntegrationViewSet(NautobotModelViewSet):
391
- queryset = ExternalIntegration.objects.select_related("secrets_group")
385
+ queryset = ExternalIntegration.objects.all()
392
386
  serializer_class = serializers.ExternalIntegrationSerializer
393
387
  filterset_class = filters.ExternalIntegrationFilterSet
394
388
 
@@ -399,7 +393,7 @@ class ExternalIntegrationViewSet(NautobotModelViewSet):
399
393
 
400
394
 
401
395
  class FileProxyViewSet(ReadOnlyModelViewSet):
402
- queryset = FileProxy.objects.select_related("job_result")
396
+ queryset = FileProxy.objects.all()
403
397
  serializer_class = serializers.FileProxySerializer
404
398
  filterset_class = filters.FileProxyFilterSet
405
399
 
@@ -488,6 +482,7 @@ class ImageAttachmentViewSet(ModelViewSet):
488
482
  queryset = ImageAttachment.objects.all()
489
483
  serializer_class = serializers.ImageAttachmentSerializer
490
484
  filterset_class = filters.ImageAttachmentFilterSet
485
+ parser_classes = [JSONParser, NautobotCSVParser, MultiPartParser]
491
486
 
492
487
 
493
488
  #
@@ -766,13 +761,13 @@ class JobViewSet(
766
761
  ):
767
762
  lookup_value_regex = r"[-0-9a-fA-F]+"
768
763
 
769
- def perform_destroy(self, obj):
770
- if obj.module_name.startswith("nautobot."):
764
+ def perform_destroy(self, instance):
765
+ if instance.module_name.startswith("nautobot."):
771
766
  raise ProtectedError(
772
- f"Unable to delete Job {obj}. System Job cannot be deleted",
767
+ f"Unable to delete Job {instance}. System Job cannot be deleted",
773
768
  [],
774
769
  )
775
- super().perform_destroy(obj)
770
+ super().perform_destroy(instance)
776
771
 
777
772
 
778
773
  @extend_schema_view(
@@ -838,7 +833,7 @@ class JobQueueAssignmentViewSet(NautobotModelViewSet):
838
833
  Manage job queue assignments through DELETE, GET, POST, PUT, and PATCH requests.
839
834
  """
840
835
 
841
- queryset = JobQueueAssignment.objects.select_related("job", "job_queue")
836
+ queryset = JobQueueAssignment.objects.all()
842
837
  serializer_class = serializers.JobQueueAssignmentSerializer
843
838
  filterset_class = filters.JobQueueAssignmentFilterSet
844
839
 
@@ -853,7 +848,7 @@ class JobLogEntryViewSet(ReadOnlyModelViewSet):
853
848
  Retrieve a list of job log entries.
854
849
  """
855
850
 
856
- queryset = JobLogEntry.objects.select_related("job_result")
851
+ queryset = JobLogEntry.objects.all()
857
852
  serializer_class = serializers.JobLogEntrySerializer
858
853
  filterset_class = filters.JobLogEntryFilterSet
859
854
 
@@ -871,7 +866,7 @@ class JobResultViewSet(
871
866
  Retrieve a list of job results
872
867
  """
873
868
 
874
- queryset = JobResult.objects.select_related("job_model", "user")
869
+ queryset = JobResult.objects.all()
875
870
  serializer_class = serializers.JobResultSerializer
876
871
  filterset_class = filters.JobResultFilterSet
877
872
 
@@ -908,7 +903,7 @@ class ScheduledJobViewSet(ReadOnlyModelViewSet):
908
903
  Retrieve a list of scheduled jobs
909
904
  """
910
905
 
911
- queryset = ScheduledJob.objects.select_related("user")
906
+ queryset = ScheduledJob.objects.all()
912
907
  serializer_class = serializers.ScheduledJobSerializer
913
908
  filterset_class = filters.ScheduledJobFilterSet
914
909
 
@@ -1061,7 +1056,7 @@ class MetadataTypeViewSet(NautobotModelViewSet):
1061
1056
 
1062
1057
 
1063
1058
  class MetadataChoiceViewSet(ModelViewSet):
1064
- queryset = MetadataChoice.objects.select_related("metadata_type")
1059
+ queryset = MetadataChoice.objects.all()
1065
1060
  serializer_class = serializers.MetadataChoiceSerializer
1066
1061
  filterset_class = filters.MetadataChoiceFilterSet
1067
1062
 
@@ -1078,7 +1073,7 @@ class ObjectMetadataViewSet(NautobotModelViewSet):
1078
1073
 
1079
1074
 
1080
1075
  class NoteViewSet(ModelViewSet):
1081
- queryset = Note.objects.select_related("user")
1076
+ queryset = Note.objects.all()
1082
1077
  serializer_class = serializers.NoteSerializer
1083
1078
  filterset_class = filters.NoteFilterSet
1084
1079
 
@@ -1097,7 +1092,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
1097
1092
  Retrieve a list of recent changes.
1098
1093
  """
1099
1094
 
1100
- queryset = ObjectChange.objects.select_related("user")
1095
+ queryset = ObjectChange.objects.all()
1101
1096
  serializer_class = serializers.ObjectChangeSerializer
1102
1097
  filterset_class = filters.ObjectChangeFilterSet
1103
1098
 
@@ -30,6 +30,7 @@ JOB_OVERRIDABLE_FIELDS = (
30
30
  "soft_time_limit",
31
31
  "time_limit",
32
32
  "has_sensitive_variables",
33
+ "is_singleton",
33
34
  )
34
35
 
35
36
 
@@ -52,4 +53,5 @@ JOB_RESULT_CUSTOM_CELERY_KWARGS = (
52
53
  "nautobot_job_job_model_id",
53
54
  "nautobot_job_scheduled_job_id",
54
55
  "nautobot_job_user_id",
56
+ "nautobot_job_ignore_singleton_lock",
55
57
  )
@@ -119,13 +119,13 @@ __all__ = (
119
119
  "CustomFieldDateFilter",
120
120
  "CustomFieldFilterMixin",
121
121
  "CustomFieldJSONFilter",
122
+ "CustomFieldModelFilterSet",
123
+ "CustomFieldModelFilterSetMixin",
122
124
  "CustomFieldMultiSelectFilter",
123
125
  "CustomFieldMultiValueCharFilter",
124
126
  "CustomFieldMultiValueDateFilter",
125
127
  "CustomFieldMultiValueNumberFilter",
126
128
  "CustomFieldNumberFilter",
127
- "CustomFieldModelFilterSet",
128
- "CustomFieldModelFilterSetMixin",
129
129
  "CustomLinkFilterSet",
130
130
  "DynamicGroupFilterSet",
131
131
  "DynamicGroupMembershipFilterSet",
@@ -136,25 +136,25 @@ __all__ = (
136
136
  "ImageAttachmentFilterSet",
137
137
  "JobFilterSet",
138
138
  "JobLogEntryFilterSet",
139
- "JobQueueFilterSet",
140
139
  "JobQueueAssignmentFilterSet",
140
+ "JobQueueFilterSet",
141
141
  "JobResultFilterSet",
142
142
  "LocalContextFilterSet",
143
143
  "LocalContextModelFilterSetMixin",
144
- "MetadataTypeFilterSet",
145
144
  "MetadataChoiceFilterSet",
145
+ "MetadataTypeFilterSet",
146
146
  "NautobotFilterSet",
147
147
  "NoteFilterSet",
148
148
  "ObjectChangeFilterSet",
149
+ "RelationshipAssociationFilterSet",
149
150
  "RelationshipFilter",
150
151
  "RelationshipFilterSet",
151
- "RelationshipAssociationFilterSet",
152
152
  "RoleFilterSet",
153
153
  "RoleModelFilterSetMixin",
154
154
  "ScheduledJobFilterSet",
155
155
  "SecretFilterSet",
156
- "SecretsGroupFilterSet",
157
156
  "SecretsGroupAssociationFilterSet",
157
+ "SecretsGroupFilterSet",
158
158
  "StatusFilter",
159
159
  "StatusFilterSet",
160
160
  "StatusModelFilterSetMixin",
@@ -874,6 +874,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
874
874
  "is_job_button_receiver",
875
875
  "soft_time_limit",
876
876
  "time_limit",
877
+ "is_singleton",
877
878
  "grouping_override",
878
879
  "name_override",
879
880
  "approval_required_override",
@@ -883,6 +884,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
883
884
  "soft_time_limit_override",
884
885
  "time_limit_override",
885
886
  "has_sensitive_variables_override",
887
+ "is_singleton_override",
886
888
  "tags",
887
889
  ]
888
890
 
@@ -14,9 +14,9 @@ from .mixins import (
14
14
  )
15
15
 
16
16
  __all__ = (
17
- "NautobotModelForm",
18
- "NautobotFilterForm",
19
17
  "NautobotBulkEditForm",
18
+ "NautobotFilterForm",
19
+ "NautobotModelForm",
20
20
  )
21
21
 
22
22
 
@@ -1,5 +1,7 @@
1
1
  import inspect
2
+ import logging
2
3
 
4
+ from celery import chain
3
5
  from django import forms
4
6
  from django.conf import settings
5
7
  from django.contrib.auth import get_user_model
@@ -7,7 +9,7 @@ from django.contrib.contenttypes.models import ContentType
7
9
  from django.core.exceptions import ValidationError
8
10
  from django.core.validators import MinValueValidator
9
11
  from django.db.models.fields import TextField
10
- from django.forms import inlineformset_factory, ModelMultipleChoiceField
12
+ from django.forms import inlineformset_factory, ModelMultipleChoiceField, MultipleHiddenInput
11
13
  from django.urls.base import reverse
12
14
  from django.utils.timezone import get_current_timezone_name
13
15
 
@@ -35,6 +37,7 @@ from nautobot.core.forms import (
35
37
  TagFilterField,
36
38
  )
37
39
  from nautobot.core.forms.constants import BOOLEAN_WITH_BLANK_CHOICES
40
+ from nautobot.core.forms.forms import ConfirmationForm
38
41
  from nautobot.core.utils.deprecation import class_deprecated_in_favor_of
39
42
  from nautobot.dcim.models import Device, DeviceRedundancyGroup, DeviceType, Location, Platform
40
43
  from nautobot.extras.choices import (
@@ -88,9 +91,12 @@ from nautobot.extras.models import (
88
91
  Webhook,
89
92
  )
90
93
  from nautobot.extras.registry import registry
94
+ from nautobot.extras.signals import change_context_state
95
+ from nautobot.extras.tasks import delete_custom_field_data
91
96
  from nautobot.extras.utils import (
92
97
  ChangeLoggedModelsQuery,
93
98
  FeatureQuery,
99
+ get_worker_count,
94
100
  RoleModelsQuery,
95
101
  TaggableClassesQuery,
96
102
  )
@@ -111,87 +117,90 @@ from .mixins import (
111
117
  TagsBulkEditFormMixin,
112
118
  )
113
119
 
120
+ logger = logging.getLogger(__name__)
121
+
114
122
  __all__ = (
115
123
  "BaseDynamicGroupMembershipFormSet",
116
- "ComputedFieldForm",
117
124
  "ComputedFieldFilterForm",
118
- "ConfigContextForm",
125
+ "ComputedFieldForm",
119
126
  "ConfigContextBulkEditForm",
120
127
  "ConfigContextFilterForm",
121
- "ConfigContextSchemaForm",
128
+ "ConfigContextForm",
122
129
  "ConfigContextSchemaBulkEditForm",
123
130
  "ConfigContextSchemaFilterForm",
124
- "CustomFieldForm",
125
- "CustomFieldFilterForm",
126
- "CustomFieldModelCSVForm",
131
+ "ConfigContextSchemaForm",
127
132
  "CustomFieldBulkCreateForm", # 2.0 TODO remove this deprecated class
133
+ "CustomFieldBulkDeleteForm",
128
134
  "CustomFieldChoiceFormSet",
129
- "CustomLinkForm",
135
+ "CustomFieldFilterForm",
136
+ "CustomFieldForm",
137
+ "CustomFieldModelCSVForm",
130
138
  "CustomLinkFilterForm",
139
+ "CustomLinkForm",
131
140
  "DynamicGroupBulkAssignForm",
132
- "DynamicGroupForm",
133
141
  "DynamicGroupFilterForm",
142
+ "DynamicGroupForm",
134
143
  "DynamicGroupMembershipFormSet",
135
- "ExportTemplateForm",
136
144
  "ExportTemplateFilterForm",
145
+ "ExportTemplateForm",
146
+ "ExternalIntegrationBulkEditForm",
137
147
  "ExternalIntegrationFilterForm",
138
148
  "ExternalIntegrationForm",
139
- "ExternalIntegrationBulkEditForm",
140
- "GitRepositoryForm",
141
149
  "GitRepositoryBulkEditForm",
142
150
  "GitRepositoryFilterForm",
143
- "GraphQLQueryForm",
151
+ "GitRepositoryForm",
144
152
  "GraphQLQueryFilterForm",
153
+ "GraphQLQueryForm",
145
154
  "ImageAttachmentForm",
146
- "JobForm",
147
155
  "JobBulkEditForm",
148
- "JobButtonForm",
149
156
  "JobButtonBulkEditForm",
150
157
  "JobButtonFilterForm",
158
+ "JobButtonForm",
151
159
  "JobEditForm",
152
160
  "JobFilterForm",
153
- "JobHookForm",
161
+ "JobForm",
154
162
  "JobHookFilterForm",
163
+ "JobHookForm",
155
164
  "JobQueueBulkEditForm",
156
165
  "JobQueueFilterForm",
157
166
  "JobQueueForm",
158
- "JobScheduleForm",
159
167
  "JobResultFilterForm",
168
+ "JobScheduleForm",
160
169
  "LocalContextFilterForm",
161
- "LocalContextModelForm",
162
170
  "LocalContextModelBulkEditForm",
171
+ "LocalContextModelForm",
172
+ "MetadataChoiceFormSet",
163
173
  "MetadataTypeBulkEditForm",
164
- "MetadataTypeForm",
165
174
  "MetadataTypeFilterForm",
166
- "MetadataChoiceFormSet",
167
- "NoteForm",
175
+ "MetadataTypeForm",
168
176
  "NoteFilterForm",
177
+ "NoteForm",
169
178
  "ObjectChangeFilterForm",
170
179
  "ObjectMetadataFilterForm",
171
180
  "PasswordInputWithPlaceholder",
172
- "RelationshipForm",
173
- "RelationshipFilterForm",
174
181
  "RelationshipAssociationFilterForm",
182
+ "RelationshipFilterForm",
183
+ "RelationshipForm",
175
184
  "RoleBulkEditForm",
176
185
  "RoleFilterForm",
177
186
  "RoleForm",
178
187
  "SavedViewForm",
179
188
  "SavedViewModalForm",
180
189
  "ScheduledJobFilterForm",
181
- "SecretForm",
182
190
  "SecretFilterForm",
183
- "SecretsGroupForm",
184
- "SecretsGroupFilterForm",
191
+ "SecretForm",
185
192
  "SecretsGroupAssociationFormSet",
193
+ "SecretsGroupFilterForm",
194
+ "SecretsGroupForm",
186
195
  "StaticGroupAssociationFilterForm",
187
- "StatusForm",
188
- "StatusFilterForm",
189
196
  "StatusBulkEditForm",
190
- "TagForm",
191
- "TagFilterForm",
197
+ "StatusFilterForm",
198
+ "StatusForm",
192
199
  "TagBulkEditForm",
193
- "WebhookForm",
200
+ "TagFilterForm",
201
+ "TagForm",
194
202
  "WebhookFilterForm",
203
+ "WebhookForm",
195
204
  )
196
205
 
197
206
 
@@ -491,6 +500,44 @@ class CustomFieldBulkCreateForm(CustomFieldModelBulkEditFormMixin):
491
500
  """No longer needed as a separate class - use CustomFieldModelBulkEditFormMixin instead."""
492
501
 
493
502
 
503
+ class CustomFieldBulkDeleteForm(ConfirmationForm):
504
+ def __init__(self, *args, delete_all=False, **kwargs):
505
+ super().__init__(*args, **kwargs)
506
+ queryset = CustomField.objects.all()
507
+ self.fields["pk"] = ModelMultipleChoiceField(
508
+ queryset=queryset, widget=MultipleHiddenInput, required=not delete_all
509
+ )
510
+
511
+ def construct_custom_field_delete_tasks(self, queryset):
512
+ """
513
+ Helper method to construct a list of celery tasks to execute when bulk deleting custom fields.
514
+ """
515
+ change_context = change_context_state.get()
516
+ if change_context is None:
517
+ context = None
518
+ else:
519
+ context = change_context.as_dict(queryset)
520
+ context["context_detail"] = "bulk delete custom field data"
521
+ tasks = [
522
+ delete_custom_field_data.si(obj.key, set(obj.content_types.values_list("pk", flat=True)), context)
523
+ for obj in queryset
524
+ ]
525
+ return tasks
526
+
527
+ def perform_pre_delete(self, queryset):
528
+ """
529
+ Remove all Custom Field Keys/Values from _custom_field_data of the related ContentType in the background.
530
+ """
531
+ if not get_worker_count():
532
+ logger.error("Celery worker process not running. Object custom fields may fail to reflect this deletion.")
533
+ return
534
+ tasks = self.construct_custom_field_delete_tasks(queryset)
535
+ # Executing the tasks in the background sequentially using chain() aligns with how a single
536
+ # CustomField object is deleted. We decided to not check the result because it needs at least one worker
537
+ # to be active and comes with extra performance penalty.
538
+ chain(*tasks).apply_async()
539
+
540
+
494
541
  #
495
542
  # Custom Links
496
543
  #
@@ -990,6 +1037,8 @@ class JobEditForm(NautobotModelForm):
990
1037
  "job_queues",
991
1038
  "default_job_queue_override",
992
1039
  "default_job_queue",
1040
+ "is_singleton",
1041
+ "is_singleton_override",
993
1042
  "tags",
994
1043
  ]
995
1044
 
@@ -1089,6 +1138,11 @@ class JobBulkEditForm(NautobotBulkEditForm):
1089
1138
  required=False,
1090
1139
  help_text="Default Job Queue the job runs on if no Job Queue is specified",
1091
1140
  )
1141
+ is_singleton = forms.NullBooleanField(
1142
+ required=False,
1143
+ widget=BulkEditNullBooleanSelect,
1144
+ help_text="Whether this job should fail to run if another instance of this job is already running",
1145
+ )
1092
1146
  # Flags to indicate whether the above properties are inherited from the source code or overridden by the database
1093
1147
  # Text field overrides
1094
1148
  clear_grouping_override = forms.BooleanField(
@@ -1132,10 +1186,62 @@ class JobBulkEditForm(NautobotBulkEditForm):
1132
1186
  required=False,
1133
1187
  help_text="If checked, the values of has sensitive variables will be reverted to the default values defined in each Job's source code",
1134
1188
  )
1189
+ is_singleton_override = forms.BooleanField(
1190
+ required=False,
1191
+ help_text="If checked, the values of is singleton will be reverted to the default values defined in each Job's source code",
1192
+ )
1135
1193
 
1136
1194
  class Meta:
1137
1195
  model = Job
1138
1196
 
1197
+ def post_save(self, obj):
1198
+ super().post_save(obj)
1199
+
1200
+ cleaned_data = self.cleaned_data
1201
+
1202
+ # Handle text related fields
1203
+ for overridable_field in JOB_OVERRIDABLE_FIELDS:
1204
+ override_field = overridable_field + "_override"
1205
+ clear_override_field = "clear_" + overridable_field + "_override"
1206
+ reset_override = cleaned_data.get(clear_override_field, False)
1207
+ override_value = cleaned_data.get(overridable_field)
1208
+ if reset_override:
1209
+ setattr(obj, override_field, False)
1210
+ elif not reset_override and override_value not in [None, ""]:
1211
+ setattr(obj, override_field, True)
1212
+ setattr(obj, overridable_field, override_value)
1213
+
1214
+ # Handle job queues
1215
+ clear_override_field = "clear_job_queues_override"
1216
+ reset_override = cleaned_data.get(clear_override_field, False)
1217
+ if reset_override:
1218
+ meta_task_queues = obj.job_class.task_queues
1219
+ job_queues = []
1220
+ for queue_name in meta_task_queues:
1221
+ try:
1222
+ job_queues.append(JobQueue.objects.get(name=queue_name))
1223
+ except JobQueue.DoesNotExist:
1224
+ # Do we want to create the Job Queue for the users here if we do not have it in the database?
1225
+ pass
1226
+ obj.job_queues_override = False
1227
+ obj.job_queues.set(job_queues)
1228
+ elif cleaned_data["job_queues"]:
1229
+ obj.job_queues_override = True
1230
+
1231
+ # Handle default job queue
1232
+ clear_override_field = "clear_default_job_queue_override"
1233
+ reset_override = cleaned_data.get(clear_override_field, False)
1234
+ if reset_override:
1235
+ meta_task_queues = obj.job_class.task_queues
1236
+ obj.default_job_queue_override = False
1237
+ obj.default_job_queue, _ = JobQueue.objects.get_or_create(
1238
+ name=meta_task_queues[0] if meta_task_queues else settings.CELERY_TASK_DEFAULT_QUEUE
1239
+ )
1240
+ elif cleaned_data["default_job_queue"]:
1241
+ obj.default_job_queue_override = True
1242
+
1243
+ obj.validated_save()
1244
+
1139
1245
 
1140
1246
  class JobFilterForm(BootstrapMixin, forms.Form):
1141
1247
  model = Job
@@ -1779,6 +1885,8 @@ class RoleBulkEditForm(NautobotBulkEditForm):
1779
1885
 
1780
1886
  pk = forms.ModelMultipleChoiceField(queryset=Role.objects.all(), widget=forms.MultipleHiddenInput)
1781
1887
  color = forms.CharField(max_length=6, required=False, widget=ColorSelect())
1888
+ description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
1889
+ weight = forms.IntegerField(required=False)
1782
1890
  content_types = MultipleContentTypeField(
1783
1891
  queryset=RoleModelsQuery().as_queryset(), required=False, label="Content Type(s)"
1784
1892
  )
@@ -34,7 +34,7 @@ from nautobot.extras.utils import remove_prefix_from_cf_key
34
34
  logger = logging.getLogger(__name__)
35
35
 
36
36
 
37
- __all__ = (
37
+ __all__ = ( # noqa:RUF022
38
38
  "ContactTeamModelFilterFormMixin",
39
39
  "CustomFieldModelBulkEditFormMixin",
40
40
  "CustomFieldModelFilterFormMixin",
@@ -327,7 +327,7 @@ class RelationshipModelBulkEditFormMixin(BulkEditForm):
327
327
  field_name,
328
328
  instance,
329
329
  )
330
- if field_name in self.nullable_fields and field_name in nullified_fields:
330
+ if field_name in self.nullable_fields and nullified_fields and field_name in nullified_fields:
331
331
  logger.debug("Deleting existing relationship associations for %s on %s", relationship, instance)
332
332
  relationshipassociation_queryset.delete()
333
333
  elif field_name in self.cleaned_data:
@@ -673,7 +673,7 @@ class RelationshipModelFormMixin(forms.ModelForm):
673
673
  for peer_id in target_peer_ids:
674
674
  relationship = self.fields[field_name].model
675
675
  if not relationship.symmetric:
676
- association = RelationshipAssociation(
676
+ association = RelationshipAssociation( # pylint: disable=repeated-keyword
677
677
  relationship=relationship,
678
678
  **{
679
679
  f"{side}_type": self.obj_type,
@@ -837,13 +837,21 @@ class StatusModelFilterFormMixin(forms.Form):
837
837
  self.order_fields(self.field_order) # Reorder fields again
838
838
 
839
839
 
840
- class TagsBulkEditFormMixin(forms.Form):
840
+ class TagsBulkEditFormMixin(BulkEditForm):
841
841
  def __init__(self, *args, **kwargs):
842
842
  super().__init__(*args, **kwargs)
843
843
 
844
844
  # Add add/remove tags fields
845
- self.fields["add_tags"] = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False)
846
- self.fields["remove_tags"] = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False)
845
+ self.fields["add_tags"] = DynamicModelMultipleChoiceField(
846
+ queryset=Tag.objects.all(),
847
+ query_params={"content_types": self.model._meta.label_lower},
848
+ required=False,
849
+ )
850
+ self.fields["remove_tags"] = DynamicModelMultipleChoiceField(
851
+ queryset=Tag.objects.all(),
852
+ query_params={"content_types": self.model._meta.label_lower},
853
+ required=False,
854
+ )
847
855
 
848
856
 
849
857
  # 2.2 TODO: Names below are only for backward compatibility with Nautobot 1.3 and earlier. Remove in 2.2
@@ -8,15 +8,15 @@ from django.contrib.auth.models import Group
8
8
  logger = logging.getLogger(__name__)
9
9
 
10
10
 
11
- CLAIMS_GROUP_NAME = getattr(settings, "NAUTOBOT_SSO_CLAIMS_GROUP", "groups")
11
+ CLAIMS_GROUP_NAME = getattr(settings, "SSO_CLAIMS_GROUP", "groups")
12
12
  """ Which claim to look at in the OAuth2/OIDC response
13
13
 
14
14
  For Okta you can look at `Okta -> Authorization Servers -> Claims`. And a reasonable
15
15
  default is "groups". For Azure a reasonable default is "roles".
16
16
  """
17
17
 
18
- SUPERUSER_GROUPS = getattr(settings, "NAUTOBOT_SSO_SUPERUSER_GROUPS", [])
19
- STAFF_GROUPS = getattr(settings, "NAUTOBOT_SSO_STAFF_GROUPS", [])
18
+ SUPERUSER_GROUPS = getattr(settings, "SSO_SUPERUSER_GROUPS", [])
19
+ STAFF_GROUPS = getattr(settings, "SSO_STAFF_GROUPS", [])
20
20
 
21
21
 
22
22
  def group_sync(uid, user=None, response=None, *args, **kwargs):
@@ -160,5 +160,4 @@ class RedisBackend(RedisHealthCheck):
160
160
  elif client_class == "django_redis.client.DefaultClient":
161
161
  self.check_redis(redis_url=location, **options.get("CONNECTION_POOL_KWARGS", {}))
162
162
  else:
163
- if self.redis_url is None:
164
- self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
163
+ self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))