nautobot 2.4.0__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 (592) 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 +0 -1
  18. nautobot/circuits/api/views.py +8 -4
  19. nautobot/circuits/tables.py +1 -2
  20. nautobot/circuits/templates/circuits/circuit_create.html +7 -1
  21. nautobot/circuits/views.py +3 -3
  22. nautobot/cloud/api/views.py +10 -6
  23. nautobot/cloud/models.py +1 -1
  24. nautobot/cloud/views.py +16 -0
  25. nautobot/core/api/fields.py +5 -5
  26. nautobot/core/api/filter_backends.py +9 -3
  27. nautobot/core/api/schema.py +2 -13
  28. nautobot/core/api/serializers.py +34 -40
  29. nautobot/core/api/views.py +4 -56
  30. nautobot/core/celery/log.py +4 -4
  31. nautobot/core/celery/schedulers.py +1 -1
  32. nautobot/core/choices.py +2 -2
  33. nautobot/core/events/__init__.py +3 -3
  34. nautobot/core/filters.py +16 -21
  35. nautobot/core/fixtures/user-data.json +59 -0
  36. nautobot/core/forms/__init__.py +19 -19
  37. nautobot/core/forms/fields.py +11 -14
  38. nautobot/core/forms/forms.py +2 -33
  39. nautobot/core/graphql/types.py +1 -1
  40. nautobot/core/jobs/__init__.py +7 -28
  41. nautobot/core/jobs/cleanup.py +12 -48
  42. nautobot/core/jobs/groups.py +1 -1
  43. nautobot/core/management/commands/validate_models.py +1 -1
  44. nautobot/core/models/__init__.py +1 -1
  45. nautobot/core/models/query_functions.py +2 -2
  46. nautobot/core/models/tree_queries.py +3 -6
  47. nautobot/core/settings.py +2 -29
  48. nautobot/core/settings.yaml +0 -21
  49. nautobot/core/tables.py +60 -74
  50. nautobot/core/templates/inc/media.html +0 -3
  51. nautobot/core/templates/inc/nav_menu.html +0 -1
  52. nautobot/core/templates/nautobot_config.py.j2 +0 -13
  53. nautobot/core/templates/search.html +0 -7
  54. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  55. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  56. nautobot/core/templates/utilities/theme_preview.html +0 -7
  57. nautobot/core/templatetags/helpers.py +2 -11
  58. nautobot/core/testing/__init__.py +8 -8
  59. nautobot/core/testing/api.py +15 -170
  60. nautobot/core/testing/filters.py +2 -25
  61. nautobot/core/testing/forms.py +0 -2
  62. nautobot/core/testing/mixins.py +2 -7
  63. nautobot/core/testing/views.py +29 -44
  64. nautobot/core/tests/integration/test_app_home.py +1 -0
  65. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  66. nautobot/core/tests/integration/test_filters.py +2 -0
  67. nautobot/core/tests/integration/test_home.py +1 -0
  68. nautobot/core/tests/integration/test_navbar.py +1 -0
  69. nautobot/core/tests/integration/test_view_authentication.py +0 -1
  70. nautobot/core/tests/runner.py +1 -1
  71. nautobot/core/tests/test_api.py +1 -98
  72. nautobot/core/tests/test_csv.py +3 -25
  73. nautobot/core/tests/test_forms.py +0 -1
  74. nautobot/core/tests/test_jobs.py +1 -303
  75. nautobot/core/tests/test_settings_schema.py +0 -7
  76. nautobot/core/tests/test_tables.py +0 -100
  77. nautobot/core/tests/test_utils.py +1 -63
  78. nautobot/core/tests/test_views.py +3 -30
  79. nautobot/core/ui/nav.py +0 -1
  80. nautobot/core/ui/object_detail.py +1 -15
  81. nautobot/core/urls.py +0 -11
  82. nautobot/core/utils/lookup.py +8 -11
  83. nautobot/core/utils/requests.py +9 -24
  84. nautobot/core/views/__init__.py +0 -42
  85. nautobot/core/views/generic.py +176 -78
  86. nautobot/core/views/mixins.py +34 -94
  87. nautobot/core/views/renderers.py +6 -6
  88. nautobot/dcim/api/serializers.py +62 -54
  89. nautobot/dcim/api/views.py +113 -47
  90. nautobot/dcim/filters/__init__.py +2 -31
  91. nautobot/dcim/forms.py +17 -36
  92. nautobot/dcim/graphql/types.py +2 -2
  93. nautobot/dcim/models/__init__.py +1 -1
  94. nautobot/dcim/models/device_component_templates.py +2 -2
  95. nautobot/dcim/models/device_components.py +20 -22
  96. nautobot/dcim/models/devices.py +1 -10
  97. nautobot/dcim/models/locations.py +3 -3
  98. nautobot/dcim/models/power.py +5 -6
  99. nautobot/dcim/models/racks.py +4 -4
  100. nautobot/dcim/tables/__init__.py +3 -3
  101. nautobot/dcim/tables/devices.py +5 -7
  102. nautobot/dcim/tables/devicetypes.py +2 -2
  103. nautobot/dcim/tables/racks.py +1 -1
  104. nautobot/dcim/templates/dcim/controller_create.html +7 -1
  105. nautobot/dcim/templates/dcim/controller_retrieve.html +9 -1
  106. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +0 -2
  107. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +0 -5
  108. nautobot/dcim/templates/dcim/device.html +9 -1
  109. nautobot/dcim/templates/dcim/device_edit.html +37 -36
  110. nautobot/dcim/templates/dcim/location.html +9 -1
  111. nautobot/dcim/templates/dcim/location_edit.html +7 -1
  112. nautobot/dcim/templates/dcim/rack.html +9 -1
  113. nautobot/dcim/templates/dcim/rack_edit.html +7 -1
  114. nautobot/dcim/templates/dcim/rackreservation.html +9 -1
  115. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +9 -1
  116. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +7 -1
  117. nautobot/dcim/tests/test_api.py +3 -16
  118. nautobot/dcim/tests/test_filters.py +0 -33
  119. nautobot/dcim/tests/test_forms.py +2 -51
  120. nautobot/dcim/tests/test_graphql.py +0 -52
  121. nautobot/dcim/tests/test_models.py +5 -34
  122. nautobot/dcim/tests/test_views.py +83 -21
  123. nautobot/dcim/views.py +13 -1
  124. nautobot/extras/api/customfields.py +2 -2
  125. nautobot/extras/api/serializers.py +85 -90
  126. nautobot/extras/api/views.py +27 -22
  127. nautobot/extras/constants.py +0 -2
  128. nautobot/extras/filters/__init__.py +6 -8
  129. nautobot/extras/forms/base.py +2 -2
  130. nautobot/extras/forms/forms.py +31 -139
  131. nautobot/extras/forms/mixins.py +5 -13
  132. nautobot/extras/group_sync.py +3 -3
  133. nautobot/extras/health_checks.py +2 -1
  134. nautobot/extras/jobs.py +12 -70
  135. nautobot/extras/managers.py +1 -3
  136. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  137. nautobot/extras/models/__init__.py +1 -1
  138. nautobot/extras/models/contacts.py +1 -1
  139. nautobot/extras/models/customfields.py +11 -12
  140. nautobot/extras/models/groups.py +9 -11
  141. nautobot/extras/models/jobs.py +4 -23
  142. nautobot/extras/models/models.py +2 -2
  143. nautobot/extras/plugins/__init__.py +2 -13
  144. nautobot/extras/plugins/marketplace_manifest.yml +79 -84
  145. nautobot/extras/plugins/tables.py +14 -16
  146. nautobot/extras/plugins/views.py +69 -65
  147. nautobot/extras/registry.py +1 -1
  148. nautobot/extras/secrets/__init__.py +2 -2
  149. nautobot/extras/tables.py +5 -7
  150. nautobot/extras/templates/extras/dynamicgroup.html +9 -1
  151. nautobot/extras/templates/extras/job_detail.html +0 -16
  152. nautobot/extras/templates/extras/job_edit.html +0 -1
  153. nautobot/extras/templates/extras/jobqueue_retrieve.html +9 -1
  154. nautobot/extras/templates/extras/marketplace.html +11 -29
  155. nautobot/extras/templates/extras/plugin_detail.html +15 -32
  156. nautobot/extras/templates/extras/plugins_tiles.html +10 -21
  157. nautobot/extras/test_jobs/api_test_job.py +1 -1
  158. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  159. nautobot/extras/test_jobs/dry_run.py +1 -1
  160. nautobot/extras/test_jobs/fail.py +5 -5
  161. nautobot/extras/test_jobs/file_output.py +1 -1
  162. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  163. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  164. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  165. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  166. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  167. nautobot/extras/test_jobs/log_redaction.py +1 -1
  168. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  169. nautobot/extras/test_jobs/modify_db.py +1 -1
  170. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  171. nautobot/extras/test_jobs/object_var_required.py +1 -1
  172. nautobot/extras/test_jobs/object_vars.py +1 -1
  173. nautobot/extras/test_jobs/pass.py +3 -3
  174. nautobot/extras/test_jobs/profiling.py +1 -1
  175. nautobot/extras/test_jobs/relative_import.py +3 -3
  176. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  177. nautobot/extras/test_jobs/task_queues.py +1 -1
  178. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  179. nautobot/extras/tests/test_api.py +13 -13
  180. nautobot/extras/tests/test_customfields.py +1 -1
  181. nautobot/extras/tests/test_datasources.py +1 -2
  182. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  183. nautobot/extras/tests/test_filters.py +6 -6
  184. nautobot/extras/tests/test_forms.py +1 -20
  185. nautobot/extras/tests/test_jobs.py +19 -160
  186. nautobot/extras/tests/test_models.py +10 -10
  187. nautobot/extras/tests/test_plugins.py +9 -62
  188. nautobot/extras/tests/test_relationships.py +9 -120
  189. nautobot/extras/tests/test_views.py +191 -52
  190. nautobot/extras/utils.py +2 -3
  191. nautobot/extras/views.py +98 -30
  192. nautobot/ipam/api/fields.py +3 -3
  193. nautobot/ipam/api/serializers.py +33 -41
  194. nautobot/ipam/api/views.py +117 -68
  195. nautobot/ipam/factory.py +1 -1
  196. nautobot/ipam/filters.py +2 -3
  197. nautobot/ipam/lookups.py +62 -101
  198. nautobot/ipam/models.py +16 -66
  199. nautobot/ipam/querysets.py +2 -2
  200. nautobot/ipam/tables.py +7 -23
  201. nautobot/ipam/templates/ipam/ipaddress.html +9 -1
  202. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +7 -1
  203. nautobot/ipam/templates/ipam/ipaddress_edit.html +7 -1
  204. nautobot/ipam/templates/ipam/prefix.html +9 -1
  205. nautobot/ipam/templates/ipam/prefix_edit.html +7 -1
  206. nautobot/ipam/templates/ipam/vlan.html +9 -1
  207. nautobot/ipam/templates/ipam/vlan_edit.html +7 -1
  208. nautobot/ipam/templates/ipam/vrf_edit.html +7 -1
  209. nautobot/ipam/tests/test_api.py +3 -416
  210. nautobot/ipam/tests/test_forms.py +47 -49
  211. nautobot/ipam/tests/test_migrations.py +30 -30
  212. nautobot/ipam/tests/test_models.py +34 -95
  213. nautobot/ipam/tests/test_querysets.py +1 -63
  214. nautobot/ipam/tests/test_views.py +0 -3
  215. nautobot/ipam/utils/__init__.py +6 -36
  216. nautobot/ipam/views.py +87 -61
  217. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  218. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  219. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +2 -40
  220. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  221. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  222. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  223. nautobot/project-static/docs/404.html +4 -46
  224. nautobot/project-static/docs/apps/index.html +4 -46
  225. nautobot/project-static/docs/apps/nautobot-apps.html +6 -47
  226. nautobot/project-static/docs/assets/_mkdocstrings.css +1 -25
  227. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  228. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  229. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +10 -62
  230. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +7 -59
  231. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +122 -374
  232. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +18 -90
  233. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +21 -95
  234. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +6 -53
  235. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +5 -52
  236. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +17 -79
  237. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +28 -102
  238. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +21 -108
  239. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +38 -131
  240. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +65 -239
  241. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +165 -581
  242. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +36 -109
  243. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +167 -453
  244. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +211 -493
  245. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +8 -60
  246. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +15 -71
  247. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +55 -407
  248. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +205 -585
  249. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +412 -858
  250. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +7 -59
  251. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +186 -448
  252. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +147 -365
  253. nautobot/project-static/docs/development/apps/api/configuration-view.html +4 -46
  254. nautobot/project-static/docs/development/apps/api/database-backend-config.html +4 -46
  255. nautobot/project-static/docs/development/apps/api/models/django-admin.html +4 -46
  256. nautobot/project-static/docs/development/apps/api/models/global-search.html +4 -46
  257. nautobot/project-static/docs/development/apps/api/models/graphql.html +4 -46
  258. nautobot/project-static/docs/development/apps/api/models/index.html +4 -46
  259. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +4 -46
  260. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +4 -46
  261. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +4 -46
  262. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +4 -46
  263. nautobot/project-static/docs/development/apps/api/platform-features/index.html +4 -46
  264. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +4 -46
  265. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +4 -46
  266. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +4 -46
  267. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +4 -46
  268. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +7 -68
  269. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +4 -46
  270. nautobot/project-static/docs/development/apps/api/prometheus.html +4 -46
  271. nautobot/project-static/docs/development/apps/api/setup.html +4 -46
  272. nautobot/project-static/docs/development/apps/api/testing.html +4 -46
  273. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +4 -46
  274. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +4 -46
  275. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +4 -46
  276. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +4 -46
  277. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +4 -46
  278. nautobot/project-static/docs/development/apps/api/views/base-template.html +4 -46
  279. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +4 -46
  280. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +4 -46
  281. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +4 -46
  282. nautobot/project-static/docs/development/apps/api/views/index.html +4 -46
  283. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +4 -46
  284. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +4 -46
  285. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +4 -46
  286. nautobot/project-static/docs/development/apps/api/views/notes.html +4 -46
  287. nautobot/project-static/docs/development/apps/api/views/rest-api.html +6 -52
  288. nautobot/project-static/docs/development/apps/api/views/urls.html +4 -46
  289. nautobot/project-static/docs/development/apps/index.html +4 -46
  290. nautobot/project-static/docs/development/apps/migration/code-updates.html +4 -46
  291. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +4 -46
  292. nautobot/project-static/docs/development/apps/migration/from-v1.html +4 -46
  293. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +4 -46
  294. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +4 -46
  295. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +4 -46
  296. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +4 -46
  297. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +8 -50
  298. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +4 -46
  299. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +14 -211
  300. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +4 -46
  301. nautobot/project-static/docs/development/apps/porting-from-netbox.html +4 -46
  302. nautobot/project-static/docs/development/core/application-registry.html +4 -46
  303. nautobot/project-static/docs/development/core/best-practices.html +4 -46
  304. nautobot/project-static/docs/development/core/bootstrap-ui.html +4 -46
  305. nautobot/project-static/docs/development/core/caching.html +4 -46
  306. nautobot/project-static/docs/development/core/controllers.html +4 -46
  307. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +74 -73
  308. nautobot/project-static/docs/development/core/generic-views.html +4 -46
  309. nautobot/project-static/docs/development/core/getting-started.html +224 -249
  310. nautobot/project-static/docs/development/core/homepage.html +7 -49
  311. nautobot/project-static/docs/development/core/index.html +4 -46
  312. nautobot/project-static/docs/development/core/{minikube-dev-environment-for-k8s-jobs.html → local-k8s.html} +168 -469
  313. nautobot/project-static/docs/development/core/model-checklist.html +12 -56
  314. nautobot/project-static/docs/development/core/model-features.html +4 -46
  315. nautobot/project-static/docs/development/core/natural-keys.html +4 -46
  316. nautobot/project-static/docs/development/core/navigation-menu.html +4 -46
  317. nautobot/project-static/docs/development/core/release-checklist.html +7 -49
  318. nautobot/project-static/docs/development/core/role-internals.html +4 -46
  319. nautobot/project-static/docs/development/core/settings.html +4 -46
  320. nautobot/project-static/docs/development/core/style-guide.html +7 -49
  321. nautobot/project-static/docs/development/core/templates.html +4 -46
  322. nautobot/project-static/docs/development/core/testing.html +4 -46
  323. nautobot/project-static/docs/development/core/ui-component-framework.html +273 -369
  324. nautobot/project-static/docs/development/core/user-preferences.html +4 -46
  325. nautobot/project-static/docs/development/index.html +4 -46
  326. nautobot/project-static/docs/development/jobs/index.html +122 -216
  327. nautobot/project-static/docs/development/jobs/migration/from-v1.html +4 -46
  328. nautobot/project-static/docs/index.html +23 -54
  329. nautobot/project-static/docs/objects.inv +0 -0
  330. nautobot/project-static/docs/overview/application_stack.html +7 -47
  331. nautobot/project-static/docs/overview/design_philosophy.html +4 -46
  332. nautobot/project-static/docs/release-notes/index.html +12 -52
  333. nautobot/project-static/docs/release-notes/version-1.0.html +193 -234
  334. nautobot/project-static/docs/release-notes/version-1.1.html +190 -231
  335. nautobot/project-static/docs/release-notes/version-1.2.html +265 -306
  336. nautobot/project-static/docs/release-notes/version-1.3.html +291 -332
  337. nautobot/project-static/docs/release-notes/version-1.4.html +377 -417
  338. nautobot/project-static/docs/release-notes/version-1.5.html +566 -605
  339. nautobot/project-static/docs/release-notes/version-1.6.html +447 -904
  340. nautobot/project-static/docs/release-notes/version-2.0.html +489 -528
  341. nautobot/project-static/docs/release-notes/version-2.1.html +324 -363
  342. nautobot/project-static/docs/release-notes/version-2.2.html +317 -356
  343. nautobot/project-static/docs/release-notes/version-2.3.html +352 -997
  344. nautobot/project-static/docs/release-notes/version-2.4.html +101 -417
  345. nautobot/project-static/docs/requirements.txt +2 -2
  346. nautobot/project-static/docs/search/search_index.json +1 -1
  347. nautobot/project-static/docs/sitemap.xml +287 -295
  348. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  349. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +4 -46
  350. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +4 -46
  351. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +6 -48
  352. nautobot/project-static/docs/user-guide/administration/configuration/index.html +4 -46
  353. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +4 -46
  354. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +8 -110
  355. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +4 -46
  356. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +4 -46
  357. nautobot/project-static/docs/user-guide/administration/guides/docker.html +4 -46
  358. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +4 -46
  359. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +4 -46
  360. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +4 -46
  361. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +4 -46
  362. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +4 -46
  363. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +6 -48
  364. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +4 -46
  365. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +4 -46
  366. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +4 -46
  367. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +8 -66
  368. nautobot/project-static/docs/user-guide/administration/installation/index.html +4 -46
  369. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +5 -47
  370. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +4 -46
  371. nautobot/project-static/docs/user-guide/administration/installation/services.html +4 -46
  372. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +4 -46
  373. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +4 -46
  374. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +4 -46
  375. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +4 -46
  376. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +4 -46
  377. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +4 -46
  378. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +4 -46
  379. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +4 -46
  380. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +4 -46
  381. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +8 -49
  382. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +4 -46
  383. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +4 -46
  384. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +4 -46
  385. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +4 -46
  386. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +4 -46
  387. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +4 -46
  388. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +4 -46
  389. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +4 -46
  390. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +4 -46
  391. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +4 -46
  392. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +4 -46
  393. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +4 -46
  394. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +4 -46
  395. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +4 -46
  396. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +4 -46
  397. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +4 -46
  398. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +4 -46
  399. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +4 -46
  400. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +4 -46
  401. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +4 -46
  402. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +4 -46
  403. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +4 -46
  404. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +4 -46
  405. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +4 -46
  406. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +4 -46
  407. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +4 -46
  408. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +4 -46
  409. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +4 -46
  410. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +4 -46
  411. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +4 -46
  412. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +4 -46
  413. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +4 -46
  414. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +4 -46
  415. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +4 -46
  416. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +4 -46
  417. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +4 -46
  418. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +4 -46
  419. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +4 -46
  420. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +4 -46
  421. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +4 -46
  422. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +4 -46
  423. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +4 -46
  424. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +4 -46
  425. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +4 -46
  426. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +4 -46
  427. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +4 -46
  428. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +4 -46
  429. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +4 -46
  430. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +4 -46
  431. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +4 -46
  432. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +4 -46
  433. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +4 -46
  434. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +4 -46
  435. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -46
  436. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +4 -46
  437. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +4 -46
  438. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +4 -46
  439. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +12 -50
  440. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +4 -46
  441. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +4 -46
  442. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +4 -46
  443. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +4 -46
  444. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +4 -46
  445. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +4 -46
  446. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +4 -46
  447. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +4 -46
  448. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +4 -46
  449. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +4 -46
  450. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +4 -46
  451. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +4 -46
  452. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +7 -49
  453. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +4 -46
  454. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +4 -46
  455. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +4 -46
  456. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +4 -46
  457. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +4 -46
  458. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +4 -46
  459. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +4 -46
  460. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +4 -46
  461. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +4 -46
  462. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +4 -46
  463. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +4 -46
  464. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +4 -46
  465. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +4 -46
  466. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +4 -46
  467. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +4 -46
  468. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +4 -46
  469. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +4 -46
  470. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -46
  471. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +4 -46
  472. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +4 -46
  473. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +4 -46
  474. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +4 -46
  475. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +7 -51
  476. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +4 -46
  477. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +4 -46
  478. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +4 -46
  479. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +7 -49
  480. nautobot/project-static/docs/user-guide/index.html +4 -46
  481. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +4 -46
  482. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +8 -50
  483. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +4 -46
  484. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +4 -46
  485. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +4 -46
  486. nautobot/project-static/docs/user-guide/platform-functionality/events.html +4 -46
  487. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +4 -46
  488. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +4 -46
  489. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +4 -46
  490. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +4 -46
  491. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +4 -46
  492. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +4 -46
  493. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +7 -50
  494. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +4 -46
  495. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +7 -49
  496. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +4 -46
  497. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +4 -46
  498. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +4 -46
  499. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +4 -46
  500. nautobot/project-static/docs/user-guide/platform-functionality/note.html +4 -46
  501. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +4 -46
  502. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +5 -47
  503. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +4 -46
  504. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +4 -46
  505. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +25 -94
  506. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +5 -74
  507. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +4 -46
  508. nautobot/project-static/docs/user-guide/platform-functionality/role.html +4 -46
  509. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +4 -46
  510. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +4 -46
  511. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +4 -46
  512. nautobot/project-static/docs/user-guide/platform-functionality/status.html +4 -46
  513. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +4 -46
  514. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +4 -46
  515. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +4 -46
  516. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +4 -46
  517. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +4 -46
  518. nautobot/project-static/js/forms.js +1 -1
  519. nautobot/tenancy/api/views.py +13 -9
  520. nautobot/tenancy/views.py +2 -4
  521. nautobot/users/admin.py +1 -1
  522. nautobot/users/api/serializers.py +4 -5
  523. nautobot/users/api/views.py +3 -3
  524. nautobot/virtualization/api/serializers.py +4 -4
  525. nautobot/virtualization/api/views.py +24 -5
  526. nautobot/virtualization/filters.py +3 -20
  527. nautobot/virtualization/models.py +1 -1
  528. nautobot/virtualization/tables.py +2 -2
  529. nautobot/virtualization/templates/virtualization/cluster_edit.html +7 -1
  530. nautobot/virtualization/templates/virtualization/virtualmachine.html +9 -1
  531. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +8 -2
  532. nautobot/virtualization/tests/test_filters.py +0 -17
  533. nautobot/wireless/filters.py +2 -2
  534. nautobot/wireless/forms.py +1 -1
  535. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +9 -1
  536. nautobot/wireless/tests/test_filters.py +1 -29
  537. nautobot/wireless/views.py +10 -0
  538. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +6 -6
  539. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +543 -591
  540. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  541. nautobot/core/api/constants.py +0 -11
  542. nautobot/core/jobs/bulk_actions.py +0 -248
  543. nautobot/core/templates/about.html +0 -67
  544. nautobot/core/templates/inc/tenancy_form_panel.html +0 -9
  545. nautobot/core/templates/inc/tenant_table_row.html +0 -11
  546. nautobot/core/utils/querysets.py +0 -64
  547. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +0 -25
  548. nautobot/dcim/tests/integration/test_controller.py +0 -62
  549. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +0 -71
  550. nautobot/dcim/tests/test_jobs.py +0 -118
  551. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +0 -22
  552. nautobot/extras/migrations/0121_alter_team_contacts.py +0 -17
  553. nautobot/extras/test_jobs/singleton.py +0 -16
  554. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  555. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  556. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  557. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  558. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  559. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  560. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  561. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  562. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  563. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  564. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  565. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  566. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  567. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  568. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  569. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  570. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  571. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  572. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  573. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -9444
  587. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -9722
  588. nautobot/wireless/tests/integration/__init__.py +0 -0
  589. nautobot/wireless/tests/integration/test_radio_profile.py +0 -42
  590. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  591. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  592. {nautobot-2.4.0.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,5 @@
1
1
  import inspect
2
- import logging
3
2
 
4
- from celery import chain
5
3
  from django import forms
6
4
  from django.conf import settings
7
5
  from django.contrib.auth import get_user_model
@@ -9,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType
9
7
  from django.core.exceptions import ValidationError
10
8
  from django.core.validators import MinValueValidator
11
9
  from django.db.models.fields import TextField
12
- from django.forms import inlineformset_factory, ModelMultipleChoiceField, MultipleHiddenInput
10
+ from django.forms import inlineformset_factory, ModelMultipleChoiceField
13
11
  from django.urls.base import reverse
14
12
  from django.utils.timezone import get_current_timezone_name
15
13
 
@@ -37,7 +35,6 @@ from nautobot.core.forms import (
37
35
  TagFilterField,
38
36
  )
39
37
  from nautobot.core.forms.constants import BOOLEAN_WITH_BLANK_CHOICES
40
- from nautobot.core.forms.forms import ConfirmationForm
41
38
  from nautobot.core.utils.deprecation import class_deprecated_in_favor_of
42
39
  from nautobot.dcim.models import Device, DeviceRedundancyGroup, DeviceType, Location, Platform
43
40
  from nautobot.extras.choices import (
@@ -91,12 +88,9 @@ from nautobot.extras.models import (
91
88
  Webhook,
92
89
  )
93
90
  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
96
91
  from nautobot.extras.utils import (
97
92
  ChangeLoggedModelsQuery,
98
93
  FeatureQuery,
99
- get_worker_count,
100
94
  RoleModelsQuery,
101
95
  TaggableClassesQuery,
102
96
  )
@@ -117,90 +111,87 @@ from .mixins import (
117
111
  TagsBulkEditFormMixin,
118
112
  )
119
113
 
120
- logger = logging.getLogger(__name__)
121
-
122
114
  __all__ = (
123
115
  "BaseDynamicGroupMembershipFormSet",
124
- "ComputedFieldFilterForm",
125
116
  "ComputedFieldForm",
117
+ "ComputedFieldFilterForm",
118
+ "ConfigContextForm",
126
119
  "ConfigContextBulkEditForm",
127
120
  "ConfigContextFilterForm",
128
- "ConfigContextForm",
121
+ "ConfigContextSchemaForm",
129
122
  "ConfigContextSchemaBulkEditForm",
130
123
  "ConfigContextSchemaFilterForm",
131
- "ConfigContextSchemaForm",
132
- "CustomFieldBulkCreateForm", # 2.0 TODO remove this deprecated class
133
- "CustomFieldBulkDeleteForm",
134
- "CustomFieldChoiceFormSet",
135
- "CustomFieldFilterForm",
136
124
  "CustomFieldForm",
125
+ "CustomFieldFilterForm",
137
126
  "CustomFieldModelCSVForm",
138
- "CustomLinkFilterForm",
127
+ "CustomFieldBulkCreateForm", # 2.0 TODO remove this deprecated class
128
+ "CustomFieldChoiceFormSet",
139
129
  "CustomLinkForm",
130
+ "CustomLinkFilterForm",
140
131
  "DynamicGroupBulkAssignForm",
141
- "DynamicGroupFilterForm",
142
132
  "DynamicGroupForm",
133
+ "DynamicGroupFilterForm",
143
134
  "DynamicGroupMembershipFormSet",
144
- "ExportTemplateFilterForm",
145
135
  "ExportTemplateForm",
146
- "ExternalIntegrationBulkEditForm",
136
+ "ExportTemplateFilterForm",
147
137
  "ExternalIntegrationFilterForm",
148
138
  "ExternalIntegrationForm",
139
+ "ExternalIntegrationBulkEditForm",
140
+ "GitRepositoryForm",
149
141
  "GitRepositoryBulkEditForm",
150
142
  "GitRepositoryFilterForm",
151
- "GitRepositoryForm",
152
- "GraphQLQueryFilterForm",
153
143
  "GraphQLQueryForm",
144
+ "GraphQLQueryFilterForm",
154
145
  "ImageAttachmentForm",
146
+ "JobForm",
155
147
  "JobBulkEditForm",
148
+ "JobButtonForm",
156
149
  "JobButtonBulkEditForm",
157
150
  "JobButtonFilterForm",
158
- "JobButtonForm",
159
151
  "JobEditForm",
160
152
  "JobFilterForm",
161
- "JobForm",
162
- "JobHookFilterForm",
163
153
  "JobHookForm",
154
+ "JobHookFilterForm",
164
155
  "JobQueueBulkEditForm",
165
156
  "JobQueueFilterForm",
166
157
  "JobQueueForm",
167
- "JobResultFilterForm",
168
158
  "JobScheduleForm",
159
+ "JobResultFilterForm",
169
160
  "LocalContextFilterForm",
170
- "LocalContextModelBulkEditForm",
171
161
  "LocalContextModelForm",
172
- "MetadataChoiceFormSet",
162
+ "LocalContextModelBulkEditForm",
173
163
  "MetadataTypeBulkEditForm",
174
- "MetadataTypeFilterForm",
175
164
  "MetadataTypeForm",
176
- "NoteFilterForm",
165
+ "MetadataTypeFilterForm",
166
+ "MetadataChoiceFormSet",
177
167
  "NoteForm",
168
+ "NoteFilterForm",
178
169
  "ObjectChangeFilterForm",
179
170
  "ObjectMetadataFilterForm",
180
171
  "PasswordInputWithPlaceholder",
181
- "RelationshipAssociationFilterForm",
182
- "RelationshipFilterForm",
183
172
  "RelationshipForm",
173
+ "RelationshipFilterForm",
174
+ "RelationshipAssociationFilterForm",
184
175
  "RoleBulkEditForm",
185
176
  "RoleFilterForm",
186
177
  "RoleForm",
187
178
  "SavedViewForm",
188
179
  "SavedViewModalForm",
189
180
  "ScheduledJobFilterForm",
190
- "SecretFilterForm",
191
181
  "SecretForm",
192
- "SecretsGroupAssociationFormSet",
193
- "SecretsGroupFilterForm",
182
+ "SecretFilterForm",
194
183
  "SecretsGroupForm",
184
+ "SecretsGroupFilterForm",
185
+ "SecretsGroupAssociationFormSet",
195
186
  "StaticGroupAssociationFilterForm",
196
- "StatusBulkEditForm",
197
- "StatusFilterForm",
198
187
  "StatusForm",
199
- "TagBulkEditForm",
200
- "TagFilterForm",
188
+ "StatusFilterForm",
189
+ "StatusBulkEditForm",
201
190
  "TagForm",
202
- "WebhookFilterForm",
191
+ "TagFilterForm",
192
+ "TagBulkEditForm",
203
193
  "WebhookForm",
194
+ "WebhookFilterForm",
204
195
  )
205
196
 
206
197
 
@@ -500,44 +491,6 @@ class CustomFieldBulkCreateForm(CustomFieldModelBulkEditFormMixin):
500
491
  """No longer needed as a separate class - use CustomFieldModelBulkEditFormMixin instead."""
501
492
 
502
493
 
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
-
541
494
  #
542
495
  # Custom Links
543
496
  #
@@ -1037,8 +990,6 @@ class JobEditForm(NautobotModelForm):
1037
990
  "job_queues",
1038
991
  "default_job_queue_override",
1039
992
  "default_job_queue",
1040
- "is_singleton",
1041
- "is_singleton_override",
1042
993
  "tags",
1043
994
  ]
1044
995
 
@@ -1138,11 +1089,6 @@ class JobBulkEditForm(NautobotBulkEditForm):
1138
1089
  required=False,
1139
1090
  help_text="Default Job Queue the job runs on if no Job Queue is specified",
1140
1091
  )
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
- )
1146
1092
  # Flags to indicate whether the above properties are inherited from the source code or overridden by the database
1147
1093
  # Text field overrides
1148
1094
  clear_grouping_override = forms.BooleanField(
@@ -1186,62 +1132,10 @@ class JobBulkEditForm(NautobotBulkEditForm):
1186
1132
  required=False,
1187
1133
  help_text="If checked, the values of has sensitive variables will be reverted to the default values defined in each Job's source code",
1188
1134
  )
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
- )
1193
1135
 
1194
1136
  class Meta:
1195
1137
  model = Job
1196
1138
 
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
-
1245
1139
 
1246
1140
  class JobFilterForm(BootstrapMixin, forms.Form):
1247
1141
  model = Job
@@ -1885,8 +1779,6 @@ class RoleBulkEditForm(NautobotBulkEditForm):
1885
1779
 
1886
1780
  pk = forms.ModelMultipleChoiceField(queryset=Role.objects.all(), widget=forms.MultipleHiddenInput)
1887
1781
  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)
1890
1782
  content_types = MultipleContentTypeField(
1891
1783
  queryset=RoleModelsQuery().as_queryset(), required=False, label="Content Type(s)"
1892
1784
  )
@@ -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__ = ( # noqa:RUF022
37
+ __all__ = (
38
38
  "ContactTeamModelFilterFormMixin",
39
39
  "CustomFieldModelBulkEditFormMixin",
40
40
  "CustomFieldModelFilterFormMixin",
@@ -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( # pylint: disable=repeated-keyword
676
+ association = RelationshipAssociation(
677
677
  relationship=relationship,
678
678
  **{
679
679
  f"{side}_type": self.obj_type,
@@ -837,21 +837,13 @@ class StatusModelFilterFormMixin(forms.Form):
837
837
  self.order_fields(self.field_order) # Reorder fields again
838
838
 
839
839
 
840
- class TagsBulkEditFormMixin(BulkEditForm):
840
+ class TagsBulkEditFormMixin(forms.Form):
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(
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
- )
845
+ self.fields["add_tags"] = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False)
846
+ self.fields["remove_tags"] = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False)
855
847
 
856
848
 
857
849
  # 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, "SSO_CLAIMS_GROUP", "groups")
11
+ CLAIMS_GROUP_NAME = getattr(settings, "NAUTOBOT_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, "SSO_SUPERUSER_GROUPS", [])
19
- STAFF_GROUPS = getattr(settings, "SSO_STAFF_GROUPS", [])
18
+ SUPERUSER_GROUPS = getattr(settings, "NAUTOBOT_SSO_SUPERUSER_GROUPS", [])
19
+ STAFF_GROUPS = getattr(settings, "NAUTOBOT_SSO_STAFF_GROUPS", [])
20
20
 
21
21
 
22
22
  def group_sync(uid, user=None, response=None, *args, **kwargs):
@@ -160,4 +160,5 @@ 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
- self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
163
+ if self.redis_url is None:
164
+ self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
nautobot/extras/jobs.py CHANGED
@@ -18,7 +18,6 @@ from db_file_storage.form_widgets import DBClearableFileInput
18
18
  from django import forms
19
19
  from django.conf import settings
20
20
  from django.contrib.auth import get_user_model
21
- from django.core.cache import cache
22
21
  from django.core.exceptions import ObjectDoesNotExist
23
22
  from django.core.files.base import ContentFile
24
23
  from django.core.files.uploadedfile import UploadedFile
@@ -68,15 +67,15 @@ User = get_user_model()
68
67
 
69
68
 
70
69
  __all__ = [
70
+ "Job",
71
71
  "BooleanVar",
72
72
  "ChoiceVar",
73
73
  "FileVar",
74
+ "IntegerVar",
74
75
  "IPAddressVar",
75
76
  "IPAddressWithMaskVar",
76
77
  "IPNetworkVar",
77
- "IntegerVar",
78
78
  "JSONVar",
79
- "Job",
80
79
  "MultiChoiceVar",
81
80
  "MultiObjectVar",
82
81
  "ObjectVar",
@@ -106,16 +105,13 @@ class BaseJob:
106
105
 
107
106
  - name (str)
108
107
  - description (str)
109
- - approval_required (bool)
110
- - dryrun_default (bool)
111
- - field_order (list)
112
- - has_sensitive_variables (bool)
113
108
  - hidden (bool)
109
+ - field_order (list)
110
+ - approval_required (bool)
114
111
  - soft_time_limit (int)
115
- - task_queues (list)
116
- - template_name (str)
117
112
  - time_limit (int)
118
- - is_singleton (bool)
113
+ - has_sensitive_variables (bool)
114
+ - task_queues (list)
119
115
  """
120
116
 
121
117
  def __init__(self):
@@ -193,31 +189,6 @@ class BaseJob:
193
189
  )
194
190
  raise RunJobTaskFailed(f"Job {self.job_model} is not enabled to be run!")
195
191
 
196
- ignore_singleton_lock = self.celery_kwargs.get("nautobot_job_ignore_singleton_lock", False)
197
- if self.job_model.is_singleton:
198
- is_running = cache.get(self.singleton_cache_key)
199
- if is_running:
200
- if ignore_singleton_lock:
201
- self.logger.info(
202
- "Job %s is a singleton and already running, but singleton will be ignored because"
203
- " `ignore_singleton_lock` is set.",
204
- self.job_model,
205
- extra={"object": self.job_model, "grouping": "initialization"},
206
- )
207
- else:
208
- self.logger.error(
209
- "Job %s is a singleton and already running.",
210
- self.job_model,
211
- extra={"object": self.job_model, "grouping": "initialization"},
212
- )
213
- raise RunJobTaskFailed(f"Job '{self.job_model}' is a singleton and already running.")
214
- cache_parameters = {
215
- "key": self.singleton_cache_key,
216
- "value": 1,
217
- "timeout": self.job_model.time_limit or settings.CELERY_TASK_TIME_LIMIT,
218
- }
219
- cache.set(**cache_parameters)
220
-
221
192
  soft_time_limit = self.job_model.soft_time_limit or settings.CELERY_TASK_SOFT_TIME_LIMIT
222
193
  time_limit = self.job_model.time_limit or settings.CELERY_TASK_TIME_LIMIT
223
194
  if time_limit <= soft_time_limit:
@@ -311,14 +282,6 @@ class BaseJob:
311
282
  if status == JobResultStatusChoices.STATUS_SUCCESS:
312
283
  self.logger.success("Job completed", extra={"grouping": "post_run"})
313
284
 
314
- cache.delete(self.singleton_cache_key)
315
-
316
- @final
317
- @classproperty
318
- def singleton_cache_key(cls) -> str: # pylint: disable=no-self-argument
319
- """Cache key for singleton jobs."""
320
- return f"nautobot.extras.jobs.running.{cls.class_path}"
321
-
322
285
  @final
323
286
  @classproperty
324
287
  def file_path(cls) -> str: # pylint: disable=no-self-argument
@@ -337,7 +300,7 @@ class BaseJob:
337
300
  - my_plugin.jobs.MyPluginJob - App-provided Job
338
301
  - git_repository.jobs.myjob.MyJob - GitRepository Job
339
302
  """
340
- return f"{cls.__module__}.{cls.__name__}" # pylint: disable=no-member
303
+ return f"{cls.__module__}.{cls.__name__}"
341
304
 
342
305
  @final
343
306
  @classproperty
@@ -374,7 +337,7 @@ class BaseJob:
374
337
  @final
375
338
  @classproperty
376
339
  def name(cls) -> str: # pylint: disable=no-self-argument
377
- return cls._get_meta_attr_and_assert_type("name", cls.__name__, expected_type=str) # pylint: disable=no-member
340
+ return cls._get_meta_attr_and_assert_type("name", cls.__name__, expected_type=str)
378
341
 
379
342
  @final
380
343
  @classproperty
@@ -438,11 +401,6 @@ class BaseJob:
438
401
  def task_queues(cls) -> list: # pylint: disable=no-self-argument
439
402
  return cls._get_meta_attr_and_assert_type("task_queues", [], expected_type=(list, tuple))
440
403
 
441
- @final
442
- @classproperty
443
- def is_singleton(cls) -> bool: # pylint: disable=no-self-argument
444
- return cls._get_meta_attr_and_assert_type("is_singleton", False, expected_type=bool)
445
-
446
404
  @final
447
405
  @classproperty
448
406
  def properties_dict(cls) -> dict: # pylint: disable=no-self-argument
@@ -461,14 +419,13 @@ class BaseJob:
461
419
  "time_limit": cls.time_limit,
462
420
  "has_sensitive_variables": cls.has_sensitive_variables,
463
421
  "task_queues": cls.task_queues,
464
- "is_singleton": cls.is_singleton,
465
422
  }
466
423
 
467
424
  @final
468
425
  @classproperty
469
426
  def registered_name(cls) -> str: # pylint: disable=no-self-argument
470
427
  """Deprecated - use class_path classproperty instead."""
471
- return f"{cls.__module__}.{cls.__name__}" # pylint: disable=no-member
428
+ return f"{cls.__module__}.{cls.__name__}"
472
429
 
473
430
  @classmethod
474
431
  def _get_vars(cls):
@@ -529,19 +486,6 @@ class BaseJob:
529
486
  label="Profile job execution",
530
487
  help_text="Profiles the job execution using cProfile and outputs a report to /tmp/",
531
488
  )
532
- # If the class already exists there may be overrides, so we have to check this.
533
- try:
534
- job_model = JobModel.objects.get(module_name=cls.__module__, job_class_name=cls.__name__)
535
- is_singleton = job_model.is_singleton
536
- except JobModel.DoesNotExist:
537
- is_singleton = cls.is_singleton
538
- if is_singleton:
539
- form.fields["_ignore_singleton_lock"] = forms.BooleanField(
540
- required=False,
541
- initial=False,
542
- label="Ignore singleton lock",
543
- help_text="Allow this singleton job to run even when another instance is already running",
544
- )
545
489
 
546
490
  job_model = JobModel.objects.get_for_class_path(cls.class_path)
547
491
  dryrun_default = job_model.dryrun_default if job_model.dryrun_default_override else cls.dryrun_default
@@ -575,9 +519,7 @@ class BaseJob:
575
519
  field.disabled = True
576
520
 
577
521
  # Ensure non-Job-specific fields are still last after applying field_order
578
- for field in ["_job_queue", "_profile", "_ignore_singleton_lock"]:
579
- if field not in form.fields:
580
- continue
522
+ for field in ["_job_queue", "_profile"]:
581
523
  value = form.fields.pop(field)
582
524
  form.fields[field] = value
583
525
 
@@ -1089,7 +1031,7 @@ class JobHookReceiver(Job):
1089
1031
 
1090
1032
  object_change = ObjectVar(model=ObjectChange)
1091
1033
 
1092
- def run(self, object_change): # pylint: disable=arguments-differ
1034
+ def run(self, object_change):
1093
1035
  """JobHookReceiver subclasses generally shouldn't need to override this method."""
1094
1036
  self.receive_job_hook(
1095
1037
  change=object_change,
@@ -1118,7 +1060,7 @@ class JobButtonReceiver(Job):
1118
1060
  object_pk = StringVar()
1119
1061
  object_model_name = StringVar()
1120
1062
 
1121
- def run(self, object_pk, object_model_name): # pylint: disable=arguments-differ
1063
+ def run(self, object_pk, object_model_name):
1122
1064
  """JobButtonReceiver subclasses generally shouldn't need to override this method."""
1123
1065
  model = get_model_from_name(object_model_name)
1124
1066
  obj = model.objects.get(pk=object_pk)
@@ -22,9 +22,8 @@ class JobResultManager(BaseManager.from_queryset(RestrictedQuerySet), TaskResult
22
22
  return self.model(id=task_id)
23
23
 
24
24
  @transaction_retry(max_retries=2)
25
- def store_result( # pylint:disable=arguments-differ # Nautobot adds kwargs like job_model_id and scheduled_job_id
25
+ def store_result(
26
26
  self,
27
- *,
28
27
  task_id,
29
28
  result,
30
29
  status,
@@ -42,7 +41,6 @@ class JobResultManager(BaseManager.from_queryset(RestrictedQuerySet), TaskResult
42
41
  using=None,
43
42
  content_type=None,
44
43
  content_encoding=None,
45
- **kwargs,
46
44
  ):
47
45
  """
48
46
  Store the result and status of a Celery task.
@@ -2,6 +2,7 @@ from collections import OrderedDict
2
2
 
3
3
  from django.db import migrations
4
4
 
5
+ from nautobot.extras.choices import LogLevelChoices
5
6
  from nautobot.extras.constants import (
6
7
  JOB_LOG_MAX_ABSOLUTE_URL_LENGTH,
7
8
  JOB_LOG_MAX_GROUPING_LENGTH,
@@ -122,13 +123,14 @@ def reverse_migrate_params(apps, schema_editor):
122
123
  ]
123
124
  )
124
125
 
125
- job_result.data[entry.grouping].setdefault(entry.log_level, 0)
126
- job_result.data[entry.grouping][entry.log_level] += 1
127
- if "total" not in job_result.data:
128
- job_result.data["total"] = _data_grouping_struct()
129
- del job_result.data["total"]["log"]
130
- job_result.data["total"].setdefault(entry.log_level, 0)
131
- job_result.data["total"][entry.log_level] += 1
126
+ if entry.log_level != LogLevelChoices.LOG_DEFAULT:
127
+ job_result.data[entry.grouping].setdefault(entry.log_level, 0)
128
+ job_result.data[entry.grouping][entry.log_level] += 1
129
+ if "total" not in job_result.data:
130
+ job_result.data["total"] = _data_grouping_struct()
131
+ del job_result.data["total"]["log"]
132
+ job_result.data["total"].setdefault(entry.log_level, 0)
133
+ job_result.data["total"][entry.log_level] += 1
132
134
 
133
135
  job_result.save()
134
136
 
@@ -77,8 +77,8 @@ __all__ = (
77
77
  "ObjectChange",
78
78
  "ObjectMetadata",
79
79
  "Relationship",
80
- "RelationshipAssociation",
81
80
  "RelationshipModel",
81
+ "RelationshipAssociation",
82
82
  "Role",
83
83
  "RoleField",
84
84
  "SavedView",
@@ -61,7 +61,7 @@ class Contact(ContactTeamSharedBase):
61
61
  class Team(ContactTeamSharedBase):
62
62
  """A group of Contacts, usable interchangeably with a single Contact in most cases."""
63
63
 
64
- contacts = models.ManyToManyField(to=Contact, related_name="teams", blank=True)
64
+ contacts = models.ManyToManyField(to=Contact, related_name="teams")
65
65
 
66
66
  class Meta(ContactTeamSharedBase.Meta):
67
67
  abstract = False
@@ -578,13 +578,7 @@ class CustomField(
578
578
  )
579
579
 
580
580
  def to_form_field(
581
- self,
582
- set_initial=True,
583
- enforce_required=True,
584
- for_csv_import=False,
585
- simple_json_filter=False,
586
- label=None,
587
- for_filter_form=False,
581
+ self, set_initial=True, enforce_required=True, for_csv_import=False, simple_json_filter=False, label=None
588
582
  ):
589
583
  """
590
584
  Return a form field suitable for setting a CustomField's value for an object.
@@ -596,7 +590,6 @@ class CustomField(
596
590
  this is *not* used for CSV imports since 2.0, but it *is* used for JSON/YAML import of DeviceTypes.
597
591
  simple_json_filter: Return a TextInput widget for JSON filtering instead of the default TextArea widget.
598
592
  label: Set the input label manually (if required); otherwise, defaults to field's __str__() implementation.
599
- for_filter_form: If True return the relevant form field for filter form
600
593
  """
601
594
  initial = self.default if set_initial else None
602
595
  required = self.required if enforce_required else False
@@ -683,7 +676,7 @@ class CustomField(
683
676
  default_choice = self.custom_field_choices.filter(value=self.default).first()
684
677
 
685
678
  # Set the initial value to the first available choice (if any)
686
- if self.type == CustomFieldTypeChoices.TYPE_SELECT and not for_filter_form:
679
+ if self.type == CustomFieldTypeChoices.TYPE_SELECT:
687
680
  if not required or default_choice is None:
688
681
  choices = add_blank_choice(choices)
689
682
  field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
@@ -711,10 +704,16 @@ class CustomField(
711
704
 
712
705
  def to_filter_form_field(self, lookup_expr="exact", *args, **kwargs):
713
706
  """Return a filter form field suitable for filtering a CustomField's value for an object."""
714
- form_field = self.to_form_field(*args, **kwargs, for_filter_form=True)
715
- # We would handle type selection differently because: If lookup_type is not the same as exact, use MultiValueCharInput
707
+ form_field = self.to_form_field(*args, **kwargs)
708
+ # We would handle type selection differently because:
709
+ # 1. We'd need to use StaticSelect2Multiple for lookup_type 'exact' because self.type `select` uses StaticSelect2 by default.
710
+ # 2. Remove the blank choice since StaticSelect2Multiple is always blank and interprets the blank choice as an extra option.
711
+ # 3. If lookup_type is not the same as exact, use MultiValueCharInput
716
712
  if self.type == CustomFieldTypeChoices.TYPE_SELECT:
717
- if lookup_expr not in ["exact", "contains"]:
713
+ if lookup_expr in ["exact", "contains"]:
714
+ choices = form_field.choices[1:]
715
+ form_field.widget = StaticSelect2Multiple(choices=choices)
716
+ else:
718
717
  form_field.widget = MultiValueCharInput()
719
718
  return form_field
720
719