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

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

Potentially problematic release.


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

Files changed (675) hide show
  1. nautobot/__init__.py +15 -0
  2. nautobot/apps/api.py +0 -2
  3. nautobot/apps/config.py +32 -3
  4. nautobot/apps/events.py +19 -0
  5. nautobot/apps/exceptions.py +0 -2
  6. nautobot/apps/ui.py +44 -9
  7. nautobot/apps/utils.py +0 -8
  8. nautobot/apps/views.py +2 -0
  9. nautobot/circuits/navigation.py +0 -57
  10. nautobot/circuits/tables.py +1 -2
  11. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
  12. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
  13. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
  15. nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
  16. nautobot/circuits/tests/integration/test_relationships.py +33 -24
  17. nautobot/circuits/tests/test_filters.py +4 -8
  18. nautobot/circuits/views.py +143 -26
  19. nautobot/cloud/factory.py +4 -1
  20. nautobot/cloud/models.py +1 -1
  21. nautobot/cloud/tests/test_filters.py +5 -4
  22. nautobot/core/api/fields.py +5 -5
  23. nautobot/core/api/metadata.py +28 -256
  24. nautobot/core/api/pagination.py +3 -2
  25. nautobot/core/api/renderers.py +3 -0
  26. nautobot/core/api/serializers.py +24 -244
  27. nautobot/core/api/urls.py +3 -4
  28. nautobot/core/api/utils.py +0 -62
  29. nautobot/core/api/views.py +48 -158
  30. nautobot/core/apps/__init__.py +22 -578
  31. nautobot/core/celery/__init__.py +13 -0
  32. nautobot/core/celery/log.py +4 -4
  33. nautobot/core/celery/schedulers.py +48 -3
  34. nautobot/core/cli/__init__.py +8 -0
  35. nautobot/core/constants.py +7 -0
  36. nautobot/core/events/__init__.py +116 -0
  37. nautobot/core/events/base.py +27 -0
  38. nautobot/core/events/exceptions.py +10 -0
  39. nautobot/core/events/redis_broker.py +48 -0
  40. nautobot/core/events/syslog_broker.py +19 -0
  41. nautobot/core/exceptions.py +0 -6
  42. nautobot/core/filters.py +16 -21
  43. nautobot/core/fixtures/user-data.json +59 -0
  44. nautobot/core/forms/fields.py +53 -8
  45. nautobot/core/forms/utils.py +2 -1
  46. nautobot/core/graphql/schema.py +3 -1
  47. nautobot/core/graphql/types.py +1 -1
  48. nautobot/core/jobs/__init__.py +4 -4
  49. nautobot/core/jobs/cleanup.py +13 -49
  50. nautobot/core/jobs/groups.py +1 -1
  51. nautobot/core/management/commands/generate_test_data.py +21 -0
  52. nautobot/core/management/commands/validate_models.py +1 -1
  53. nautobot/core/middleware.py +16 -0
  54. nautobot/core/models/__init__.py +1 -1
  55. nautobot/core/models/fields.py +11 -7
  56. nautobot/core/models/query_functions.py +2 -2
  57. nautobot/core/models/tree_queries.py +3 -6
  58. nautobot/core/settings.py +44 -7
  59. nautobot/core/settings.yaml +86 -8
  60. nautobot/core/tables.py +15 -65
  61. nautobot/core/tasks.py +1 -1
  62. nautobot/core/templates/components/button/default.html +7 -0
  63. nautobot/core/templates/components/button/dropdown.html +20 -0
  64. nautobot/core/templates/components/layout/one_over_two.html +19 -0
  65. nautobot/core/templates/components/layout/two_over_one.html +19 -0
  66. nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
  67. nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
  68. nautobot/core/templates/components/panel/body_content_tags.html +6 -0
  69. nautobot/core/templates/components/panel/body_content_text.html +12 -0
  70. nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
  71. nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
  72. nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
  73. nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
  74. nautobot/core/templates/components/panel/footer_content_table.html +14 -0
  75. nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
  76. nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
  77. nautobot/core/templates/components/panel/panel.html +16 -0
  78. nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
  79. nautobot/core/templates/components/tab/content_wrapper.html +3 -0
  80. nautobot/core/templates/components/tab/label_wrapper.html +5 -0
  81. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
  82. nautobot/core/templates/generic/object_retrieve.html +28 -17
  83. nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
  84. nautobot/core/templates/inc/custom_fields/panel.html +2 -2
  85. nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
  86. nautobot/core/templates/inc/footer.html +1 -0
  87. nautobot/core/templates/inc/media.html +0 -3
  88. nautobot/core/templates/inc/nav_menu.html +1 -1
  89. nautobot/core/templates/inc/relationships_panel.html +1 -1
  90. nautobot/core/templates/nautobot_config.py.j2 +3 -3
  91. nautobot/core/templates/panel_table.html +12 -0
  92. nautobot/core/templates/search.html +0 -7
  93. nautobot/core/templates/utilities/render_jinja2.html +117 -0
  94. nautobot/core/templatetags/helpers.py +101 -12
  95. nautobot/core/templatetags/ui_framework.py +40 -0
  96. nautobot/core/testing/api.py +23 -128
  97. nautobot/core/testing/context.py +18 -0
  98. nautobot/core/testing/filters.py +41 -58
  99. nautobot/core/testing/mixins.py +2 -7
  100. nautobot/core/testing/views.py +25 -123
  101. nautobot/core/tests/integration/test_app_home.py +1 -0
  102. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  103. nautobot/core/tests/integration/test_filters.py +2 -0
  104. nautobot/core/tests/integration/test_home.py +1 -0
  105. nautobot/core/tests/integration/test_navbar.py +1 -0
  106. nautobot/core/tests/integration/test_view_authentication.py +1 -2
  107. nautobot/core/tests/nautobot_config.py +198 -0
  108. nautobot/core/tests/runner.py +3 -3
  109. nautobot/core/tests/test_api.py +82 -201
  110. nautobot/core/tests/test_csv.py +3 -25
  111. nautobot/core/tests/test_events.py +214 -0
  112. nautobot/core/tests/test_jinja_filters.py +1 -0
  113. nautobot/core/tests/test_jobs.py +84 -13
  114. nautobot/core/tests/test_navigations.py +7 -241
  115. nautobot/core/tests/test_templatetags_helpers.py +16 -0
  116. nautobot/core/tests/test_ui.py +150 -0
  117. nautobot/core/tests/test_utils.py +0 -25
  118. nautobot/core/tests/test_views.py +123 -31
  119. nautobot/core/ui/__init__.py +0 -0
  120. nautobot/core/ui/base.py +11 -0
  121. nautobot/core/ui/choices.py +44 -0
  122. nautobot/core/ui/homepage.py +167 -0
  123. nautobot/core/ui/nav.py +279 -0
  124. nautobot/core/ui/object_detail.py +1841 -0
  125. nautobot/core/ui/utils.py +36 -0
  126. nautobot/core/urls.py +4 -9
  127. nautobot/core/utils/config.py +30 -3
  128. nautobot/core/utils/lookup.py +20 -13
  129. nautobot/core/views/__init__.py +6 -1
  130. nautobot/core/views/generic.py +47 -52
  131. nautobot/core/views/mixins.py +15 -25
  132. nautobot/core/views/paginator.py +8 -5
  133. nautobot/core/views/renderers.py +3 -3
  134. nautobot/core/views/utils.py +11 -0
  135. nautobot/core/wsgi.py +3 -3
  136. nautobot/dcim/api/serializers.py +80 -179
  137. nautobot/dcim/api/urls.py +5 -0
  138. nautobot/dcim/api/views.py +17 -4
  139. nautobot/dcim/apps.py +1 -0
  140. nautobot/dcim/choices.py +28 -0
  141. nautobot/dcim/factory.py +58 -0
  142. nautobot/dcim/filters/__init__.py +197 -24
  143. nautobot/dcim/forms.py +203 -12
  144. nautobot/dcim/graphql/types.py +2 -2
  145. nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
  146. nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
  147. nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
  148. nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
  149. nautobot/dcim/models/__init__.py +4 -0
  150. nautobot/dcim/models/device_component_templates.py +2 -2
  151. nautobot/dcim/models/device_components.py +20 -22
  152. nautobot/dcim/models/devices.py +173 -4
  153. nautobot/dcim/models/locations.py +3 -3
  154. nautobot/dcim/models/power.py +5 -6
  155. nautobot/dcim/models/racks.py +6 -6
  156. nautobot/dcim/navigation.py +25 -224
  157. nautobot/dcim/signals.py +44 -0
  158. nautobot/dcim/tables/__init__.py +5 -3
  159. nautobot/dcim/tables/devices.py +96 -2
  160. nautobot/dcim/tables/devicetypes.py +2 -2
  161. nautobot/dcim/templates/dcim/controller/base.html +10 -0
  162. nautobot/dcim/templates/dcim/controller_create.html +1 -0
  163. nautobot/dcim/templates/dcim/controller_retrieve.html +5 -1
  164. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
  165. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +66 -0
  166. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +46 -0
  167. nautobot/dcim/templates/dcim/device/base.html +6 -42
  168. nautobot/dcim/templates/dcim/device/wireless.html +73 -0
  169. nautobot/dcim/templates/dcim/device.html +3 -1
  170. nautobot/dcim/templates/dcim/interface.html +1 -0
  171. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  172. nautobot/dcim/templates/dcim/locationtype.html +0 -107
  173. nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
  174. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +76 -0
  175. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +34 -0
  176. nautobot/dcim/tests/test_api.py +172 -61
  177. nautobot/dcim/tests/test_filters.py +171 -109
  178. nautobot/dcim/tests/test_forms.py +2 -51
  179. nautobot/dcim/tests/test_graphql.py +0 -52
  180. nautobot/dcim/tests/test_models.py +126 -4
  181. nautobot/dcim/tests/test_signals.py +1 -0
  182. nautobot/dcim/tests/test_views.py +103 -11
  183. nautobot/dcim/urls.py +72 -27
  184. nautobot/dcim/utils.py +2 -2
  185. nautobot/dcim/views.py +369 -62
  186. nautobot/extras/api/customfields.py +2 -2
  187. nautobot/extras/api/serializers.py +91 -75
  188. nautobot/extras/api/urls.py +4 -0
  189. nautobot/extras/api/views.py +78 -15
  190. nautobot/extras/choices.py +13 -0
  191. nautobot/extras/constants.py +0 -1
  192. nautobot/extras/context_managers.py +23 -6
  193. nautobot/extras/datasources/git.py +4 -1
  194. nautobot/extras/factory.py +27 -0
  195. nautobot/extras/filters/__init__.py +59 -0
  196. nautobot/extras/forms/forms.py +125 -30
  197. nautobot/extras/forms/mixins.py +3 -11
  198. nautobot/extras/graphql/types.py +25 -1
  199. nautobot/extras/group_sync.py +3 -3
  200. nautobot/extras/health_checks.py +2 -1
  201. nautobot/extras/jobs.py +62 -26
  202. nautobot/extras/management/__init__.py +1 -0
  203. nautobot/extras/management/commands/runjob.py +7 -79
  204. nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
  205. nautobot/extras/management/utils.py +87 -0
  206. nautobot/extras/managers.py +1 -3
  207. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  208. nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
  209. nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
  210. nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
  211. nautobot/extras/models/__init__.py +4 -0
  212. nautobot/extras/models/change_logging.py +7 -3
  213. nautobot/extras/models/customfields.py +11 -12
  214. nautobot/extras/models/groups.py +9 -13
  215. nautobot/extras/models/jobs.py +218 -37
  216. nautobot/extras/models/models.py +2 -2
  217. nautobot/extras/models/relationships.py +69 -1
  218. nautobot/extras/models/secrets.py +5 -0
  219. nautobot/extras/navigation.py +20 -262
  220. nautobot/extras/plugins/__init__.py +56 -32
  221. nautobot/extras/plugins/marketplace_manifest.yml +450 -0
  222. nautobot/extras/plugins/urls.py +1 -0
  223. nautobot/extras/plugins/views.py +48 -1
  224. nautobot/extras/signals.py +39 -1
  225. nautobot/extras/tables.py +40 -6
  226. nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
  227. nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
  228. nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
  229. nautobot/extras/templates/extras/job_detail.html +36 -6
  230. nautobot/extras/templates/extras/job_edit.html +5 -2
  231. nautobot/extras/templates/extras/job_list.html +2 -7
  232. nautobot/extras/templates/extras/jobqueue_retrieve.html +44 -0
  233. nautobot/extras/templates/extras/marketplace.html +278 -0
  234. nautobot/extras/templates/extras/plugins_list.html +35 -1
  235. nautobot/extras/templates/extras/plugins_tiles.html +79 -0
  236. nautobot/extras/templates/extras/role_retrieve.html +16 -0
  237. nautobot/extras/templates/extras/secret.html +0 -65
  238. nautobot/extras/templates/extras/secret_check.js +16 -0
  239. nautobot/extras/templates/extras/secret_create.html +114 -0
  240. nautobot/extras/templates/extras/secret_edit.html +1 -114
  241. nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
  242. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
  243. nautobot/extras/templatetags/job_buttons.py +5 -4
  244. nautobot/extras/templatetags/plugins.py +69 -6
  245. nautobot/extras/test_jobs/api_test_job.py +1 -1
  246. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  247. nautobot/extras/test_jobs/dry_run.py +1 -1
  248. nautobot/extras/test_jobs/fail.py +5 -5
  249. nautobot/extras/test_jobs/file_output.py +1 -1
  250. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  251. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  252. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  253. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  254. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  255. nautobot/extras/test_jobs/log_redaction.py +1 -1
  256. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  257. nautobot/extras/test_jobs/modify_db.py +1 -1
  258. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  259. nautobot/extras/test_jobs/object_var_required.py +1 -1
  260. nautobot/extras/test_jobs/object_vars.py +1 -1
  261. nautobot/extras/test_jobs/pass.py +3 -3
  262. nautobot/extras/test_jobs/profiling.py +1 -1
  263. nautobot/extras/test_jobs/relative_import.py +3 -3
  264. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  265. nautobot/extras/test_jobs/task_queues.py +1 -1
  266. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  267. nautobot/extras/tests/test_api.py +157 -55
  268. nautobot/extras/tests/test_context_managers.py +4 -1
  269. nautobot/extras/tests/test_customfields.py +1 -1
  270. nautobot/extras/tests/test_datasources.py +1 -2
  271. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  272. nautobot/extras/tests/test_filters.py +219 -535
  273. nautobot/extras/tests/test_forms.py +1 -20
  274. nautobot/extras/tests/test_job_variables.py +73 -152
  275. nautobot/extras/tests/test_jobs.py +43 -54
  276. nautobot/extras/tests/test_models.py +71 -16
  277. nautobot/extras/tests/test_relationships.py +5 -2
  278. nautobot/extras/tests/test_utils.py +23 -2
  279. nautobot/extras/tests/test_views.py +183 -43
  280. nautobot/extras/tests/test_webhooks.py +2 -1
  281. nautobot/extras/urls.py +2 -20
  282. nautobot/extras/utils.py +118 -4
  283. nautobot/extras/views.py +203 -92
  284. nautobot/extras/webhooks.py +5 -2
  285. nautobot/ipam/api/fields.py +3 -3
  286. nautobot/ipam/api/serializers.py +36 -137
  287. nautobot/ipam/api/views.py +93 -62
  288. nautobot/ipam/lookups.py +62 -101
  289. nautobot/ipam/models.py +11 -63
  290. nautobot/ipam/navigation.py +0 -90
  291. nautobot/ipam/querysets.py +2 -2
  292. nautobot/ipam/tables.py +6 -20
  293. nautobot/ipam/templates/ipam/routetarget.html +0 -28
  294. nautobot/ipam/templates/ipam/vrf.html +0 -47
  295. nautobot/ipam/tests/test_api.py +8 -419
  296. nautobot/ipam/tests/test_filters.py +39 -119
  297. nautobot/ipam/tests/test_forms.py +47 -51
  298. nautobot/ipam/tests/test_migrations.py +30 -30
  299. nautobot/ipam/tests/test_models.py +0 -41
  300. nautobot/ipam/tests/test_querysets.py +1 -63
  301. nautobot/ipam/urls.py +3 -69
  302. nautobot/ipam/utils/__init__.py +0 -24
  303. nautobot/ipam/views.py +153 -198
  304. nautobot/project-static/css/base.css +38 -3
  305. nautobot/project-static/docs/404.html +421 -19
  306. nautobot/project-static/docs/apps/index.html +421 -19
  307. nautobot/project-static/docs/apps/nautobot-apps.html +421 -19
  308. nautobot/project-static/docs/assets/extra.css +5 -1
  309. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  310. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  311. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +421 -19
  312. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +421 -19
  313. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +421 -172
  314. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +421 -19
  315. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +421 -19
  316. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +425 -21
  317. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +421 -19
  318. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +424 -22
  319. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9809 -0
  320. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +424 -63
  321. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +421 -19
  322. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +421 -19
  323. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +457 -20
  324. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +421 -19
  325. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +425 -25
  326. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +457 -19
  327. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +421 -19
  328. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +421 -19
  329. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +425 -215
  330. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +430 -342
  331. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5799 -1054
  332. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +421 -19
  333. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +447 -176
  334. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +460 -21
  335. nautobot/project-static/docs/development/apps/api/configuration-view.html +421 -19
  336. nautobot/project-static/docs/development/apps/api/database-backend-config.html +421 -19
  337. nautobot/project-static/docs/development/apps/api/models/django-admin.html +421 -19
  338. nautobot/project-static/docs/development/apps/api/models/global-search.html +421 -19
  339. nautobot/project-static/docs/development/apps/api/models/graphql.html +421 -19
  340. nautobot/project-static/docs/development/apps/api/models/index.html +421 -19
  341. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +421 -19
  342. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +421 -19
  343. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +421 -19
  344. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +421 -19
  345. nautobot/project-static/docs/development/apps/api/platform-features/index.html +421 -19
  346. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +421 -19
  347. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +421 -19
  348. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +421 -19
  349. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +421 -19
  350. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +424 -41
  351. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +421 -19
  352. nautobot/project-static/docs/development/apps/api/prometheus.html +421 -19
  353. nautobot/project-static/docs/development/apps/api/setup.html +425 -155
  354. nautobot/project-static/docs/development/apps/api/testing.html +421 -19
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +421 -19
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +421 -19
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +421 -19
  358. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +421 -19
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +701 -130
  360. nautobot/project-static/docs/development/apps/api/views/base-template.html +421 -19
  361. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +421 -19
  362. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +421 -19
  363. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +421 -19
  364. nautobot/project-static/docs/development/apps/api/views/index.html +423 -20
  365. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +425 -19
  366. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +451 -19
  367. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +421 -19
  368. nautobot/project-static/docs/development/apps/api/views/notes.html +421 -19
  369. nautobot/project-static/docs/development/apps/api/views/rest-api.html +421 -19
  370. nautobot/project-static/docs/development/apps/api/views/urls.html +421 -19
  371. nautobot/project-static/docs/development/apps/index.html +421 -19
  372. nautobot/project-static/docs/development/apps/migration/code-updates.html +422 -52
  373. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +422 -20
  374. nautobot/project-static/docs/development/apps/migration/from-v1.html +421 -19
  375. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +421 -19
  376. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +421 -19
  377. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +421 -19
  378. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +424 -22
  379. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9219 -0
  380. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9333 -0
  381. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9474 -0
  382. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9517 -0
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +424 -22
  384. nautobot/project-static/docs/development/core/application-registry.html +421 -19
  385. nautobot/project-static/docs/development/core/best-practices.html +421 -19
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +421 -19
  387. nautobot/project-static/docs/development/core/caching.html +421 -19
  388. nautobot/project-static/docs/development/core/controllers.html +423 -19
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +490 -45
  390. nautobot/project-static/docs/development/core/generic-views.html +421 -19
  391. nautobot/project-static/docs/development/core/getting-started.html +566 -179
  392. nautobot/project-static/docs/development/core/homepage.html +432 -30
  393. nautobot/project-static/docs/development/core/index.html +421 -19
  394. nautobot/project-static/docs/development/core/local-k8s.html +9453 -0
  395. nautobot/project-static/docs/development/core/model-checklist.html +424 -22
  396. nautobot/project-static/docs/development/core/model-features.html +421 -19
  397. nautobot/project-static/docs/development/core/natural-keys.html +421 -19
  398. nautobot/project-static/docs/development/core/navigation-menu.html +438 -26
  399. nautobot/project-static/docs/development/core/release-checklist.html +435 -45
  400. nautobot/project-static/docs/development/core/role-internals.html +421 -19
  401. nautobot/project-static/docs/development/core/settings.html +421 -19
  402. nautobot/project-static/docs/development/core/style-guide.html +421 -19
  403. nautobot/project-static/docs/development/core/templates.html +431 -22
  404. nautobot/project-static/docs/development/core/testing.html +421 -19
  405. nautobot/project-static/docs/development/core/ui-component-framework.html +11020 -0
  406. nautobot/project-static/docs/development/core/user-preferences.html +424 -22
  407. nautobot/project-static/docs/development/index.html +421 -19
  408. nautobot/project-static/docs/development/jobs/index.html +546 -160
  409. nautobot/project-static/docs/development/jobs/migration/from-v1.html +421 -19
  410. nautobot/project-static/docs/index.html +421 -19
  411. nautobot/project-static/docs/media/development/core/ui-component-framework/basic-panel-layout.png +0 -0
  412. nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.png +0 -0
  413. nautobot/project-static/docs/media/development/core/ui-component-framework/dropdown-button-example.png +0 -0
  414. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
  415. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
  416. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example.png +0 -0
  417. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
  418. nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
  419. nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
  420. nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
  421. nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
  422. nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
  423. nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
  424. nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
  425. nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
  426. nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
  427. nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +426 -20
  430. nautobot/project-static/docs/overview/design_philosophy.html +421 -19
  431. nautobot/project-static/docs/release-notes/index.html +445 -22
  432. nautobot/project-static/docs/release-notes/version-1.0.html +421 -19
  433. nautobot/project-static/docs/release-notes/version-1.1.html +421 -19
  434. nautobot/project-static/docs/release-notes/version-1.2.html +421 -19
  435. nautobot/project-static/docs/release-notes/version-1.3.html +421 -19
  436. nautobot/project-static/docs/release-notes/version-1.4.html +421 -19
  437. nautobot/project-static/docs/release-notes/version-1.5.html +421 -19
  438. nautobot/project-static/docs/release-notes/version-1.6.html +634 -667
  439. nautobot/project-static/docs/release-notes/version-2.0.html +421 -19
  440. nautobot/project-static/docs/release-notes/version-2.1.html +421 -19
  441. nautobot/project-static/docs/release-notes/version-2.2.html +421 -19
  442. nautobot/project-static/docs/release-notes/version-2.3.html +684 -886
  443. nautobot/project-static/docs/release-notes/version-2.4.html +10007 -0
  444. nautobot/project-static/docs/requirements.txt +2 -2
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +334 -270
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +421 -19
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +421 -19
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +423 -21
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +433 -32
  452. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +421 -19
  453. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +765 -180
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +421 -19
  455. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +421 -19
  456. nautobot/project-static/docs/user-guide/administration/guides/docker.html +434 -29
  457. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +421 -19
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +421 -19
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +421 -19
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +421 -19
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +421 -19
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +421 -19
  463. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +421 -19
  464. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +421 -19
  465. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +421 -19
  466. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +421 -19
  467. nautobot/project-static/docs/user-guide/administration/installation/index.html +426 -20
  468. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +421 -19
  469. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +421 -19
  470. nautobot/project-static/docs/user-guide/administration/installation/services.html +421 -19
  471. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +421 -19
  472. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +442 -41
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +435 -66
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +435 -66
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +421 -19
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +421 -19
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +421 -19
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +421 -19
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +421 -19
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +421 -19
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +421 -19
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +421 -19
  484. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +427 -21
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +421 -19
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +421 -19
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +421 -19
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +421 -19
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +421 -19
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +421 -19
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +421 -19
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +421 -19
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +421 -19
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +421 -19
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +421 -19
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +421 -19
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +421 -19
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +421 -19
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +421 -19
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +421 -19
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +421 -19
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +457 -20
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +447 -22
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +421 -19
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +421 -19
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +421 -19
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +421 -19
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +421 -19
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +421 -19
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +421 -19
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +421 -19
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +421 -19
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +421 -19
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +421 -19
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +421 -19
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +421 -19
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +421 -19
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +421 -19
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +421 -19
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +421 -19
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +421 -19
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +421 -19
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +421 -19
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +421 -19
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +421 -19
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +421 -19
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +421 -19
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +421 -19
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +421 -19
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +421 -19
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +421 -19
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +421 -19
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +421 -19
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +421 -19
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +421 -19
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +421 -19
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +421 -19
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9333 -0
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +424 -22
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +421 -19
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +421 -19
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +421 -19
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +421 -19
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +421 -19
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +421 -19
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +421 -19
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +421 -19
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +421 -19
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +421 -19
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +421 -19
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +421 -19
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +421 -19
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +421 -19
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +421 -19
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +421 -19
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +421 -19
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +421 -19
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +421 -19
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +424 -22
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9271 -0
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9175 -0
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9169 -0
  563. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9235 -0
  564. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +421 -19
  565. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +421 -19
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +421 -19
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +421 -19
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +421 -19
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +421 -19
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +421 -19
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +421 -19
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +421 -19
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +421 -19
  574. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +421 -19
  575. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +421 -19
  576. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +421 -19
  577. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +421 -19
  578. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +421 -19
  579. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +421 -19
  580. nautobot/project-static/docs/user-guide/index.html +421 -19
  581. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +424 -22
  582. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +421 -19
  583. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +421 -19
  584. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +421 -19
  585. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +421 -19
  586. nautobot/project-static/docs/user-guide/platform-functionality/events.html +9575 -0
  587. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +424 -22
  588. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +421 -19
  589. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +421 -19
  590. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +421 -19
  591. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +421 -19
  592. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +421 -19
  593. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +426 -20
  594. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +424 -22
  595. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +421 -19
  596. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +421 -19
  597. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9182 -0
  598. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +424 -22
  599. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +421 -19
  600. nautobot/project-static/docs/user-guide/platform-functionality/note.html +421 -19
  601. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +421 -19
  602. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +424 -22
  603. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9250 -0
  604. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +421 -19
  605. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +421 -19
  606. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +424 -22
  607. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +421 -19
  608. nautobot/project-static/docs/user-guide/platform-functionality/role.html +421 -19
  609. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +421 -19
  610. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +421 -19
  611. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +424 -22
  612. nautobot/project-static/docs/user-guide/platform-functionality/status.html +421 -19
  613. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +421 -19
  614. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +489 -56
  615. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +421 -19
  616. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +421 -19
  617. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +421 -19
  618. nautobot/project-static/img/jinja_logo.svg +97 -0
  619. nautobot/project-static/js/forms.js +5 -0
  620. nautobot/project-static/js/nav_menu.js +2 -1
  621. nautobot/tenancy/api/serializers.py +0 -2
  622. nautobot/tenancy/factory.py +1 -1
  623. nautobot/tenancy/navigation.py +0 -29
  624. nautobot/tenancy/templates/tenancy/tenant.html +4 -91
  625. nautobot/tenancy/tests/test_filters.py +29 -134
  626. nautobot/tenancy/views.py +32 -23
  627. nautobot/users/admin.py +3 -1
  628. nautobot/users/api/serializers.py +4 -5
  629. nautobot/users/api/views.py +1 -1
  630. nautobot/users/forms.py +19 -0
  631. nautobot/users/templates/users/preferences.html +22 -0
  632. nautobot/users/tests/test_filters.py +1 -19
  633. nautobot/users/tests/test_views.py +57 -0
  634. nautobot/users/utils.py +8 -0
  635. nautobot/users/views.py +48 -11
  636. nautobot/virtualization/api/serializers.py +4 -4
  637. nautobot/virtualization/filters.py +2 -20
  638. nautobot/virtualization/navigation.py +0 -48
  639. nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
  640. nautobot/virtualization/tests/test_filters.py +57 -183
  641. nautobot/virtualization/views.py +18 -15
  642. nautobot/wireless/__init__.py +0 -0
  643. nautobot/wireless/api/__init__.py +0 -0
  644. nautobot/wireless/api/serializers.py +44 -0
  645. nautobot/wireless/api/urls.py +20 -0
  646. nautobot/wireless/api/views.py +34 -0
  647. nautobot/wireless/apps.py +8 -0
  648. nautobot/wireless/choices.py +345 -0
  649. nautobot/wireless/factory.py +138 -0
  650. nautobot/wireless/filters.py +167 -0
  651. nautobot/wireless/forms.py +283 -0
  652. nautobot/wireless/homepage.py +19 -0
  653. nautobot/wireless/migrations/0001_initial.py +223 -0
  654. nautobot/wireless/migrations/__init__.py +0 -0
  655. nautobot/wireless/models.py +207 -0
  656. nautobot/wireless/navigation.py +105 -0
  657. nautobot/wireless/tables.py +244 -0
  658. nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
  659. nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
  660. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
  661. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +64 -0
  662. nautobot/wireless/tests/__init__.py +0 -0
  663. nautobot/wireless/tests/test_api.py +247 -0
  664. nautobot/wireless/tests/test_filters.py +54 -0
  665. nautobot/wireless/tests/test_models.py +22 -0
  666. nautobot/wireless/tests/test_views.py +378 -0
  667. nautobot/wireless/urls.py +13 -0
  668. nautobot/wireless/views.py +129 -0
  669. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +11 -14
  670. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +674 -551
  671. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  672. nautobot/core/utils/navigation.py +0 -54
  673. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  674. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  675. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
nautobot/ipam/urls.py CHANGED
@@ -8,86 +8,20 @@ from .models import (
8
8
  IPAddress,
9
9
  Prefix,
10
10
  RIR,
11
- RouteTarget,
12
11
  Service,
13
12
  VLAN,
14
13
  VLANGroup,
15
- VRF,
16
14
  )
17
15
 
18
16
  app_name = "ipam"
19
17
 
20
18
  router = NautobotUIViewSetRouter()
21
- router.register("namespaces", views.NamespaceUIViewSet)
22
19
  router.register("ip-address-to-interface", views.IPAddressToInterfaceUIViewSet)
20
+ router.register("namespaces", views.NamespaceUIViewSet)
21
+ router.register("route-targets", views.RouteTargetUIViewSet)
22
+ router.register("vrfs", views.VRFUIViewSet)
23
23
 
24
24
  urlpatterns = [
25
- # VRFs
26
- path("vrfs/", views.VRFListView.as_view(), name="vrf_list"),
27
- path("vrfs/add/", views.VRFEditView.as_view(), name="vrf_add"),
28
- path("vrfs/import/", views.VRFBulkImportView.as_view(), name="vrf_import"), # 3.0 TODO: remove, unused
29
- path("vrfs/edit/", views.VRFBulkEditView.as_view(), name="vrf_bulk_edit"),
30
- path("vrfs/delete/", views.VRFBulkDeleteView.as_view(), name="vrf_bulk_delete"),
31
- path("vrfs/<uuid:pk>/", views.VRFView.as_view(), name="vrf"),
32
- path("vrfs/<uuid:pk>/edit/", views.VRFEditView.as_view(), name="vrf_edit"),
33
- path("vrfs/<uuid:pk>/delete/", views.VRFDeleteView.as_view(), name="vrf_delete"),
34
- path(
35
- "vrfs/<uuid:pk>/changelog/",
36
- ObjectChangeLogView.as_view(),
37
- name="vrf_changelog",
38
- kwargs={"model": VRF},
39
- ),
40
- path(
41
- "vrfs/<uuid:pk>/notes/",
42
- ObjectNotesView.as_view(),
43
- name="vrf_notes",
44
- kwargs={"model": VRF},
45
- ),
46
- # Route targets
47
- path("route-targets/", views.RouteTargetListView.as_view(), name="routetarget_list"),
48
- path(
49
- "route-targets/add/",
50
- views.RouteTargetEditView.as_view(),
51
- name="routetarget_add",
52
- ),
53
- path(
54
- "route-targets/import/",
55
- views.RouteTargetBulkImportView.as_view(), # 3.0 TODO: remove, unused
56
- name="routetarget_import",
57
- ),
58
- path(
59
- "route-targets/edit/",
60
- views.RouteTargetBulkEditView.as_view(),
61
- name="routetarget_bulk_edit",
62
- ),
63
- path(
64
- "route-targets/delete/",
65
- views.RouteTargetBulkDeleteView.as_view(),
66
- name="routetarget_bulk_delete",
67
- ),
68
- path("route-targets/<uuid:pk>/", views.RouteTargetView.as_view(), name="routetarget"),
69
- path(
70
- "route-targets/<uuid:pk>/edit/",
71
- views.RouteTargetEditView.as_view(),
72
- name="routetarget_edit",
73
- ),
74
- path(
75
- "route-targets/<uuid:pk>/delete/",
76
- views.RouteTargetDeleteView.as_view(),
77
- name="routetarget_delete",
78
- ),
79
- path(
80
- "route-targets/<uuid:pk>/changelog/",
81
- ObjectChangeLogView.as_view(),
82
- name="routetarget_changelog",
83
- kwargs={"model": RouteTarget},
84
- ),
85
- path(
86
- "route-targets/<uuid:pk>/notes/",
87
- ObjectNotesView.as_view(),
88
- name="routetarget_notes",
89
- kwargs={"model": RouteTarget},
90
- ),
91
25
  # RIRs
92
26
  path("rirs/", views.RIRListView.as_view(), name="rir_list"),
93
27
  path("rirs/add/", views.RIREditView.as_view(), name="rir_add"),
@@ -4,7 +4,6 @@ import netaddr
4
4
  from nautobot.core.forms.utils import compress_range
5
5
  from nautobot.dcim.models import Interface
6
6
  from nautobot.extras.models import RelationshipAssociation
7
- from nautobot.ipam.choices import PrefixTypeChoices
8
7
  from nautobot.ipam.models import Prefix, VLAN
9
8
  from nautobot.ipam.querysets import IPAddressQuerySet
10
9
  from nautobot.virtualization.models import VMInterface
@@ -26,13 +25,6 @@ def add_available_prefixes(parent, prefix_list):
26
25
  return prefix_list
27
26
 
28
27
 
29
- def get_add_available_prefixes_callback(show_available, parent):
30
- """Conditionally provide a callback for add_available_prefixes()."""
31
- if show_available:
32
- return lambda prefixes: add_available_prefixes(parent.prefix, prefixes)
33
- return lambda prefixes: prefixes
34
-
35
-
36
28
  def add_available_ipaddresses(prefix, ipaddress_list, is_pool=False):
37
29
  """
38
30
  Annotate ranges of available IP addresses within a given prefix. If is_pool is True, the first and last IP will be
@@ -89,15 +81,6 @@ def add_available_ipaddresses(prefix, ipaddress_list, is_pool=False):
89
81
  return output
90
82
 
91
83
 
92
- def get_add_available_ipaddresses_callback(show_available, parent):
93
- """Conditionally provide a callback for add_available_ipaddresses()."""
94
- if show_available:
95
- return lambda ip_addresses: add_available_ipaddresses(
96
- parent.prefix, ip_addresses, is_pool=(parent.type == PrefixTypeChoices.TYPE_POOL)
97
- )
98
- return lambda ip_addresses: ip_addresses
99
-
100
-
101
84
  def add_available_vlans(vlan_group, vlans):
102
85
  """
103
86
  Create fake records for all gaps between used VLANs
@@ -116,13 +99,6 @@ def add_available_vlans(vlan_group, vlans):
116
99
  return vlans
117
100
 
118
101
 
119
- def get_add_available_vlans_callback(show_available, vlan_group):
120
- """Conditionally provide a callback for add_available_vlans()."""
121
- if show_available:
122
- return lambda vlans: add_available_vlans(vlan_group=vlan_group, vlans=vlans)
123
- return lambda vlans: vlans
124
-
125
-
126
102
  def handle_relationship_changes_when_merging_ips(merged_ip, merged_attributes, collapsed_ips):
127
103
  """
128
104
  Update/Delete RelationshipAssociation instances after we collapsed the IPs.
nautobot/ipam/views.py CHANGED
@@ -2,9 +2,7 @@ import logging
2
2
 
3
3
  from django.conf import settings
4
4
  from django.contrib import messages
5
- from django.contrib.auth.models import AnonymousUser
6
5
  from django.core.cache import cache
7
- from django.core.exceptions import ObjectDoesNotExist
8
6
  from django.db import models, transaction
9
7
  from django.db.models import Prefetch, ProtectedError, Q
10
8
  from django.forms.models import model_to_dict
@@ -18,14 +16,18 @@ from django_tables2 import RequestConfig
18
16
  import netaddr
19
17
 
20
18
  from nautobot.cloud.tables import CloudNetworkTable
19
+ from nautobot.core.constants import MAX_PAGE_SIZE_DEFAULT
21
20
  from nautobot.core.models.querysets import count_related
21
+ from nautobot.core.ui import object_detail
22
+ from nautobot.core.ui.choices import SectionChoices
22
23
  from nautobot.core.utils.config import get_settings_or_config
23
24
  from nautobot.core.utils.permissions import get_permission_for_model
24
25
  from nautobot.core.views import generic, mixins as view_mixins
25
26
  from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
26
27
  from nautobot.core.views.utils import handle_protectederror
28
+ from nautobot.core.views.viewsets import NautobotUIViewSet
27
29
  from nautobot.dcim.models import Device, Interface, Location
28
- from nautobot.extras.models import Role, SavedView, Status, Tag
30
+ from nautobot.extras.models import Role, Status, Tag
29
31
  from nautobot.ipam import choices, constants
30
32
  from nautobot.ipam.api import serializers
31
33
  from nautobot.tenancy.models import Tenant
@@ -45,9 +47,9 @@ from .models import (
45
47
  VRF,
46
48
  )
47
49
  from .utils import (
48
- get_add_available_ipaddresses_callback,
49
- get_add_available_prefixes_callback,
50
- get_add_available_vlans_callback,
50
+ add_available_ipaddresses,
51
+ add_available_prefixes,
52
+ add_available_vlans,
51
53
  handle_relationship_changes_when_merging_ips,
52
54
  retrieve_interface_or_vminterface_from_request,
53
55
  )
@@ -103,12 +105,23 @@ class NamespaceIPAddressesView(generic.ObjectView):
103
105
 
104
106
  def get_extra_context(self, request, instance):
105
107
  # Find all IPAddresses belonging to this Namespace
106
- ip_addresses = instance.ip_addresses.restrict(request.user, "view").select_related("role", "status", "tenant")
108
+ ip_addresses = (
109
+ instance.ip_addresses.restrict(request.user, "view")
110
+ .select_related("role", "status", "tenant")
111
+ .annotate(
112
+ interface_count=count_related(Interface, "ip_addresses"),
113
+ interface_parent_count=count_related(Device, "interfaces__ip_addresses", distinct=True),
114
+ vm_interface_count=count_related(VMInterface, "ip_addresses"),
115
+ vm_interface_parent_count=count_related(VirtualMachine, "interfaces__ip_addresses", distinct=True),
116
+ )
117
+ )
107
118
 
108
- ip_address_table = tables.IPAddressTable(ip_addresses, exclude=["namespace"])
119
+ ip_address_table = tables.IPAddressTable(ip_addresses)
109
120
  if request.user.has_perm("ipam.change_ipaddress") or request.user.has_perm("ipam.delete_ipaddress"):
110
121
  ip_address_table.columns.show("pk")
111
122
 
123
+ ip_address_table.exclude = ("namespace",)
124
+
112
125
  paginate = {
113
126
  "paginator_class": EnhancedPaginator,
114
127
  "per_page": get_paginate_count(request),
@@ -145,10 +158,12 @@ class NamespacePrefixesView(generic.ObjectView):
145
158
  # Find all Prefixes belonging to this Namespace
146
159
  prefixes = instance.prefixes.restrict(request.user, "view").select_related("status")
147
160
 
148
- prefix_table = tables.PrefixTable(prefixes, exclude=["namespace"])
161
+ prefix_table = tables.PrefixTable(prefixes)
149
162
  if request.user.has_perm("ipam.change_prefix") or request.user.has_perm("ipam.delete_prefix"):
150
163
  prefix_table.columns.show("pk")
151
164
 
165
+ prefix_table.exclude = ("namespace",)
166
+
152
167
  paginate = {
153
168
  "paginator_class": EnhancedPaginator,
154
169
  "per_page": get_paginate_count(request),
@@ -185,10 +200,12 @@ class NamespaceVRFsView(generic.ObjectView):
185
200
  # Find all VRFs belonging to this Namespace
186
201
  vrfs = instance.vrfs.restrict(request.user, "view")
187
202
 
188
- vrf_table = tables.VRFTable(vrfs, exclude=["namespace"])
203
+ vrf_table = tables.VRFTable(vrfs)
189
204
  if request.user.has_perm("ipam.change_vrf") or request.user.has_perm("ipam.delete_vrf"):
190
205
  vrf_table.columns.show("pk")
191
206
 
207
+ vrf_table.exclude = ("namespace",)
208
+
192
209
  paginate = {
193
210
  "paginator_class": EnhancedPaginator,
194
211
  "per_page": get_paginate_count(request),
@@ -222,83 +239,59 @@ class NamespaceVRFsView(generic.ObjectView):
222
239
  #
223
240
 
224
241
 
225
- class VRFListView(generic.ObjectListView):
226
- queryset = VRF.objects.all()
227
- filterset = filters.VRFFilterSet
228
- filterset_form = forms.VRFFilterForm
229
- table = tables.VRFTable
230
-
231
-
232
- class VRFView(generic.ObjectView):
233
- queryset = VRF.objects.all()
234
-
235
- def get_extra_context(self, request, instance):
236
- context = super().get_extra_context(request, instance)
237
-
238
- prefixes = instance.prefixes.restrict(request.user, "view")
239
- prefix_count = prefixes.count()
240
- prefix_table = tables.PrefixTable(prefixes.select_related("namespace"), hide_hierarchy_ui=True)
241
-
242
- # devices = instance.devices.restrict(request.user, "view")
243
- # device_count = devices.count()
244
- # device_table = DeviceTable(devices.all(), orderable=False)
245
-
246
- import_targets_table = tables.RouteTargetTable(
247
- instance.import_targets.select_related("tenant"), orderable=False
248
- )
249
- export_targets_table = tables.RouteTargetTable(
250
- instance.export_targets.select_related("tenant"), orderable=False
251
- )
252
-
253
- # TODO(jathan): This table might need to live on Device and on VRFs
254
- # (possibly replacing `device_table` above.
255
- vrfs = instance.device_assignments.restrict(request.user, "view")
256
- vrf_table = tables.VRFDeviceAssignmentTable(vrfs, exclude=["vrf"])
257
- # context["vrf_table"] = vrf_table
258
-
259
- paginate = {
260
- "paginator_class": EnhancedPaginator,
261
- "per_page": get_paginate_count(request),
262
- }
263
- RequestConfig(request, paginate).configure(prefix_table)
264
- RequestConfig(request, paginate).configure(vrf_table)
265
- RequestConfig(request, paginate).configure(import_targets_table)
266
- RequestConfig(request, paginate).configure(export_targets_table)
267
-
268
- context.update(
269
- {
270
- "device_table": vrf_table,
271
- # "device_table": device_table,
272
- "prefix_count": prefix_count,
273
- "prefix_table": prefix_table,
274
- "import_targets_table": import_targets_table,
275
- "export_targets_table": export_targets_table,
276
- }
277
- )
278
-
279
- return context
280
-
281
-
282
- class VRFEditView(generic.ObjectEditView):
283
- queryset = VRF.objects.all()
284
- model_form = forms.VRFForm
285
- template_name = "ipam/vrf_edit.html"
286
-
287
-
288
- class VRFDeleteView(generic.ObjectDeleteView):
242
+ class VRFUIViewSet(NautobotUIViewSet):
289
243
  queryset = VRF.objects.all()
290
-
291
-
292
- class VRFBulkImportView(generic.BulkImportView): # 3.0 TODO: remove, unused
293
- queryset = VRF.objects.all()
294
- table = tables.VRFTable
295
-
296
-
297
- class VRFBulkEditView(generic.BulkEditView):
298
- queryset = VRF.objects.select_related("tenant")
299
- filterset = filters.VRFFilterSet
300
- table = tables.VRFTable
301
- form = forms.VRFBulkEditForm
244
+ filterset_class = filters.VRFFilterSet
245
+ filterset_form_class = forms.VRFFilterForm
246
+ table_class = tables.VRFTable
247
+ form_class = forms.VRFForm
248
+ bulk_update_form_class = forms.VRFBulkEditForm
249
+ serializer_class = serializers.VRFSerializer
250
+
251
+ object_detail_content = object_detail.ObjectDetailContent(
252
+ panels=(
253
+ object_detail.ObjectFieldsPanel(
254
+ section=SectionChoices.LEFT_HALF,
255
+ weight=100,
256
+ fields="__all__",
257
+ ),
258
+ object_detail.ObjectsTablePanel(
259
+ section=SectionChoices.RIGHT_HALF,
260
+ weight=100,
261
+ table_class=tables.RouteTargetTable,
262
+ table_filter="importing_vrfs",
263
+ table_title="Import Route Targets",
264
+ add_button_route=None,
265
+ ),
266
+ object_detail.ObjectsTablePanel(
267
+ section=SectionChoices.RIGHT_HALF,
268
+ weight=200,
269
+ table_class=tables.RouteTargetTable,
270
+ table_filter="exporting_vrfs",
271
+ table_title="Export Route Targets",
272
+ add_button_route=None,
273
+ ),
274
+ object_detail.ObjectsTablePanel(
275
+ section=SectionChoices.FULL_WIDTH,
276
+ weight=100,
277
+ table_class=tables.PrefixTable,
278
+ table_filter="vrfs",
279
+ table_title="Assigned Prefixes",
280
+ hide_hierarchy_ui=True,
281
+ exclude_columns=["namespace"],
282
+ add_button_route=None,
283
+ ),
284
+ object_detail.ObjectsTablePanel(
285
+ section=SectionChoices.FULL_WIDTH,
286
+ weight=200,
287
+ table_class=tables.VRFDeviceAssignmentTable,
288
+ table_filter="vrf",
289
+ table_title="Assigned Devices",
290
+ exclude_columns=["vrf", "namespace", "rd"],
291
+ add_button_route=None,
292
+ ),
293
+ ),
294
+ )
302
295
 
303
296
  def extra_post_save_action(self, obj, form):
304
297
  if form.cleaned_data.get("add_prefixes", None):
@@ -307,70 +300,43 @@ class VRFBulkEditView(generic.BulkEditView):
307
300
  obj.prefixes.remove(*form.cleaned_data["remove_prefixes"])
308
301
 
309
302
 
310
- class VRFBulkDeleteView(generic.BulkDeleteView):
311
- queryset = VRF.objects.select_related("tenant")
312
- filterset = filters.VRFFilterSet
313
- table = tables.VRFTable
314
-
315
-
316
303
  #
317
304
  # Route targets
318
305
  #
319
306
 
320
307
 
321
- class RouteTargetListView(generic.ObjectListView):
308
+ class RouteTargetUIViewSet(NautobotUIViewSet):
322
309
  queryset = RouteTarget.objects.all()
323
- filterset = filters.RouteTargetFilterSet
324
- filterset_form = forms.RouteTargetFilterForm
325
- table = tables.RouteTargetTable
326
-
327
-
328
- class RouteTargetView(generic.ObjectView):
329
- queryset = RouteTarget.objects.all()
330
-
331
- def get_extra_context(self, request, instance):
332
- importing_vrfs_table = tables.VRFTable(instance.importing_vrfs.select_related("tenant"), orderable=False)
333
- exporting_vrfs_table = tables.VRFTable(instance.exporting_vrfs.select_related("tenant"), orderable=False)
334
-
335
- paginate = {
336
- "paginator_class": EnhancedPaginator,
337
- "per_page": get_paginate_count(request),
338
- }
339
- RequestConfig(request, paginate).configure(importing_vrfs_table)
340
- RequestConfig(request, paginate).configure(exporting_vrfs_table)
341
-
342
- return {
343
- "importing_vrfs_table": importing_vrfs_table,
344
- "exporting_vrfs_table": exporting_vrfs_table,
345
- **super().get_extra_context(request, instance),
346
- }
347
-
348
-
349
- class RouteTargetEditView(generic.ObjectEditView):
350
- queryset = RouteTarget.objects.all()
351
- model_form = forms.RouteTargetForm
352
-
353
-
354
- class RouteTargetDeleteView(generic.ObjectDeleteView):
355
- queryset = RouteTarget.objects.all()
356
-
357
-
358
- class RouteTargetBulkImportView(generic.BulkImportView): # 3.0 TODO: remove, unused
359
- queryset = RouteTarget.objects.all()
360
- table = tables.RouteTargetTable
361
-
362
-
363
- class RouteTargetBulkEditView(generic.BulkEditView):
364
- queryset = RouteTarget.objects.select_related("tenant")
365
- filterset = filters.RouteTargetFilterSet
366
- table = tables.RouteTargetTable
367
- form = forms.RouteTargetBulkEditForm
368
-
369
-
370
- class RouteTargetBulkDeleteView(generic.BulkDeleteView):
371
- queryset = RouteTarget.objects.select_related("tenant")
372
- filterset = filters.RouteTargetFilterSet
373
- table = tables.RouteTargetTable
310
+ filterset_class = filters.RouteTargetFilterSet
311
+ filterset_form_class = forms.RouteTargetFilterForm
312
+ table_class = tables.RouteTargetTable
313
+ form_class = forms.RouteTargetForm
314
+ bulk_update_form_class = forms.RouteTargetBulkEditForm
315
+ serializer_class = serializers.RouteTargetSerializer
316
+
317
+ object_detail_content = object_detail.ObjectDetailContent(
318
+ panels=(
319
+ object_detail.ObjectFieldsPanel(
320
+ section=SectionChoices.LEFT_HALF,
321
+ weight=100,
322
+ fields="__all__",
323
+ ),
324
+ object_detail.ObjectsTablePanel(
325
+ section=SectionChoices.RIGHT_HALF,
326
+ weight=100,
327
+ table_class=tables.VRFTable,
328
+ table_filter="import_targets",
329
+ table_title="Importing VRFs",
330
+ ),
331
+ object_detail.ObjectsTablePanel(
332
+ section=SectionChoices.RIGHT_HALF,
333
+ weight=200,
334
+ table_class=tables.VRFTable,
335
+ table_filter="export_targets",
336
+ table_title="Exporting VRFs",
337
+ ),
338
+ ),
339
+ )
374
340
 
375
341
 
376
342
  #
@@ -434,7 +400,6 @@ class PrefixListView(generic.ObjectListView):
434
400
  table = tables.PrefixDetailTable
435
401
  template_name = "ipam/prefix_list.html"
436
402
  queryset = Prefix.objects.all()
437
- use_new_ui = True
438
403
 
439
404
 
440
405
  class PrefixView(generic.ObjectView):
@@ -447,12 +412,12 @@ class PrefixView(generic.ObjectView):
447
412
  "vlan__vlan_group",
448
413
  "namespace",
449
414
  ).prefetch_related("locations")
450
- use_new_ui = True
451
415
 
452
416
  def get_extra_context(self, request, instance):
453
417
  # Parent prefixes table
454
418
  parent_prefixes = instance.ancestors().restrict(request.user, "view")
455
- parent_prefix_table = tables.PrefixTable(parent_prefixes, exclude=["namespace"])
419
+ parent_prefix_table = tables.PrefixTable(parent_prefixes)
420
+ parent_prefix_table.exclude = ("namespace",)
456
421
 
457
422
  vrfs = instance.vrf_assignments.restrict(request.user, "view")
458
423
  vrf_table = tables.VRFPrefixAssignmentTable(vrfs, orderable=False)
@@ -483,19 +448,19 @@ class PrefixPrefixesView(generic.ObjectView):
483
448
 
484
449
  def get_extra_context(self, request, instance):
485
450
  # Child prefixes table
486
- child_prefixes = instance.descendants().restrict(request.user, "view")
451
+ child_prefixes = (
452
+ instance.descendants()
453
+ .restrict(request.user, "view")
454
+ .select_related("parent", "status", "role", "vlan", "namespace")
455
+ .annotate(location_count=count_related(Location, "prefixes"))
456
+ )
487
457
 
488
458
  # Add available prefixes to the table if requested
489
- data_transform_callback = get_add_available_prefixes_callback(
490
- show_available=request.GET.get("show_available", "true") == "true", parent=instance
491
- )
459
+ if child_prefixes and request.GET.get("show_available", "true") == "true":
460
+ child_prefixes = add_available_prefixes(instance.prefix, child_prefixes)
492
461
 
493
- prefix_table = tables.PrefixDetailTable(
494
- child_prefixes,
495
- hide_hierarchy_ui=True,
496
- exclude=["namespace"],
497
- data_transform_callback=data_transform_callback,
498
- )
462
+ prefix_table = tables.PrefixDetailTable(child_prefixes, hide_hierarchy_ui=True)
463
+ prefix_table.exclude = ("namespace",)
499
464
  if request.user.has_perm("ipam.change_prefix") or request.user.has_perm("ipam.delete_prefix"):
500
465
  prefix_table.columns.show("pk")
501
466
 
@@ -530,16 +495,26 @@ class PrefixIPAddressesView(generic.ObjectView):
530
495
 
531
496
  def get_extra_context(self, request, instance):
532
497
  # Find all IPAddresses belonging to this Prefix
533
- ipaddresses = instance.get_all_ips().restrict(request.user, "view")
498
+ ipaddresses = (
499
+ instance.get_all_ips()
500
+ .restrict(request.user, "view")
501
+ .select_related("role", "status", "tenant")
502
+ .prefetch_related("primary_ip4_for", "primary_ip6_for")
503
+ .annotate(
504
+ interface_count=count_related(Interface, "ip_addresses"),
505
+ interface_parent_count=count_related(Device, "interfaces__ip_addresses", distinct=True),
506
+ vm_interface_count=count_related(VMInterface, "ip_addresses"),
507
+ vm_interface_parent_count=count_related(VirtualMachine, "interfaces__ip_addresses", distinct=True),
508
+ )
509
+ )
534
510
 
535
511
  # Add available IP addresses to the table if requested
536
- data_transform_callback = get_add_available_ipaddresses_callback(
537
- show_available=request.GET.get("show_available", "true") == "true", parent=instance
538
- )
512
+ if request.GET.get("show_available", "true") == "true":
513
+ ipaddresses = add_available_ipaddresses(
514
+ instance.prefix, ipaddresses, instance.type == choices.PrefixTypeChoices.TYPE_POOL
515
+ )
539
516
 
540
- ip_table = tables.IPAddressTable(
541
- ipaddresses, exclude=["parent__namespace"], data_transform_callback=data_transform_callback
542
- )
517
+ ip_table = tables.IPAddressTable(ipaddresses)
543
518
  if request.user.has_perm("ipam.change_ipaddress") or request.user.has_perm("ipam.delete_ipaddress"):
544
519
  ip_table.columns.show("pk")
545
520
 
@@ -736,41 +711,21 @@ class PrefixBulkDeleteView(generic.BulkDeleteView):
736
711
 
737
712
 
738
713
  class IPAddressListView(generic.ObjectListView):
739
- queryset = IPAddress.objects.all()
714
+ queryset = IPAddress.objects.annotate(
715
+ interface_count=count_related(Interface, "ip_addresses"),
716
+ interface_parent_count=count_related(Device, "interfaces__ip_addresses", distinct=True),
717
+ vm_interface_count=count_related(VMInterface, "ip_addresses"),
718
+ vm_interface_parent_count=count_related(VirtualMachine, "interfaces__ip_addresses", distinct=True),
719
+ assigned_count=count_related(Interface, "ip_addresses") + count_related(VMInterface, "ip_addresses"),
720
+ )
740
721
  filterset = filters.IPAddressFilterSet
741
722
  filterset_form = forms.IPAddressFilterForm
742
723
  table = tables.IPAddressDetailTable
743
724
  template_name = "ipam/ipaddress_list.html"
744
725
 
745
- def alter_queryset(self, request):
746
- queryset = super().alter_queryset(request)
747
-
748
- # All of the below is just to determine whether we are displaying the "assigned_count" column, and if so,
749
- # perform the relevant queryset annotation. Ref: nautobot/nautobot#6605
750
- if request.user is None or isinstance(request.user, AnonymousUser):
751
- table_columns = None
752
- else:
753
- table_columns = request.user.get_config("tables.IPAddressDetailTable.columns")
754
- current_saved_view_pk = request.GET.get("saved_view", None)
755
- if current_saved_view_pk:
756
- try:
757
- current_saved_view = SavedView.objects.get(view="ipam:ipaddress_list", pk=current_saved_view_pk)
758
- view_table_config = current_saved_view.config.get("table_config", {}).get("IPAddressDetailTable", None)
759
- if view_table_config is not None:
760
- table_columns = view_table_config.get("columns", table_columns)
761
- except ObjectDoesNotExist:
762
- pass
763
-
764
- if table_columns and "assigned_count" in table_columns:
765
- queryset = queryset.annotate(
766
- assigned_count=count_related(Interface, "ip_addresses") + count_related(VMInterface, "ip_addresses"),
767
- )
768
- return queryset
769
-
770
726
 
771
727
  class IPAddressView(generic.ObjectView):
772
728
  queryset = IPAddress.objects.select_related("tenant", "status", "role")
773
- use_new_ui = True
774
729
 
775
730
  def get_extra_context(self, request, instance):
776
731
  # Parent prefixes table
@@ -929,7 +884,7 @@ class IPAddressAssignView(view_mixins.GetReturnURLMixin, generic.ObjectView):
929
884
  "per_page": get_paginate_count(request),
930
885
  }
931
886
  RequestConfig(request, paginate).configure(table)
932
- max_page_size = get_settings_or_config("MAX_PAGE_SIZE")
887
+ max_page_size = get_settings_or_config("MAX_PAGE_SIZE", fallback=MAX_PAGE_SIZE_DEFAULT)
933
888
  if max_page_size and paginate["per_page"] > max_page_size:
934
889
  messages.warning(
935
890
  request,
@@ -1258,18 +1213,17 @@ class VLANGroupView(generic.ObjectView):
1258
1213
  def get_extra_context(self, request, instance):
1259
1214
  vlans = (
1260
1215
  VLAN.objects.restrict(request.user, "view")
1216
+ .annotate(location_count=count_related(Location, "vlans"))
1261
1217
  .filter(vlan_group=instance)
1262
1218
  .prefetch_related(Prefetch("prefixes", queryset=Prefix.objects.restrict(request.user)))
1263
1219
  )
1264
1220
  vlans_count = vlans.count()
1221
+ vlans = add_available_vlans(vlan_group=instance, vlans=vlans)
1265
1222
 
1266
- data_transform_callback = get_add_available_vlans_callback(show_available=True, vlan_group=instance)
1267
-
1268
- vlan_table = tables.VLANDetailTable(
1269
- vlans, exclude=["vlan_group"], data_transform_callback=data_transform_callback
1270
- )
1223
+ vlan_table = tables.VLANDetailTable(vlans)
1271
1224
  if request.user.has_perm("ipam.change_vlan") or request.user.has_perm("ipam.delete_vlan"):
1272
1225
  vlan_table.columns.show("pk")
1226
+ vlan_table.columns.hide("vlan_group")
1273
1227
 
1274
1228
  paginate = {
1275
1229
  "paginator_class": EnhancedPaginator,
@@ -1344,7 +1298,8 @@ class VLANView(generic.ObjectView):
1344
1298
  "namespace",
1345
1299
  )
1346
1300
  )
1347
- prefix_table = tables.PrefixTable(list(prefixes), hide_hierarchy_ui=True, exclude=["vlan"])
1301
+ prefix_table = tables.PrefixTable(list(prefixes), hide_hierarchy_ui=True)
1302
+ prefix_table.exclude = ("vlan",)
1348
1303
 
1349
1304
  paginate = {
1350
1305
  "paginator_class": EnhancedPaginator,