nautobot 2.4.17__py3-none-any.whl → 2.4.19__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 (627) hide show
  1. nautobot/apps/ui.py +6 -0
  2. nautobot/apps/views.py +2 -0
  3. nautobot/circuits/tables.py +1 -1
  4. nautobot/circuits/templates/circuits/circuit_create.html +7 -7
  5. nautobot/circuits/templates/circuits/circuit_retrieve.html +1 -5
  6. nautobot/circuits/templates/circuits/circuittermination_create.html +26 -26
  7. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +1 -8
  8. nautobot/circuits/templates/circuits/inc/circuit_termination.html +20 -20
  9. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +3 -3
  10. nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +9 -0
  11. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +1 -3
  12. nautobot/circuits/tests/integration/test_circuit.py +2 -2
  13. nautobot/circuits/views.py +49 -15
  14. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +1 -4
  15. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +1 -7
  16. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +1 -3
  17. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +1 -5
  18. nautobot/cloud/views.py +45 -0
  19. nautobot/core/filters.py +2 -2
  20. nautobot/core/graphql/generators.py +5 -2
  21. nautobot/core/jobs/bulk_actions.py +48 -85
  22. nautobot/core/models/querysets.py +2 -1
  23. nautobot/core/settings.py +1 -0
  24. nautobot/core/settings.yaml +9 -0
  25. nautobot/core/tables.py +21 -23
  26. nautobot/core/templates/40x.html +15 -15
  27. nautobot/core/templates/500.html +21 -21
  28. nautobot/core/templates/admin/app_index.html +8 -8
  29. nautobot/core/templates/admin/base.html +104 -104
  30. nautobot/core/templates/admin/change_form.html +65 -65
  31. nautobot/core/templates/admin/change_list.html +60 -60
  32. nautobot/core/templates/admin/change_list_results.html +39 -39
  33. nautobot/core/templates/admin/config/config.html +47 -47
  34. nautobot/core/templates/admin/delete_confirmation.html +47 -47
  35. nautobot/core/templates/admin/edit_inline/stacked.html +124 -124
  36. nautobot/core/templates/admin/edit_inline/tabular.html +60 -60
  37. nautobot/core/templates/admin/includes/fieldset.html +4 -4
  38. nautobot/core/templates/admin/index.html +60 -60
  39. nautobot/core/templates/admin/prepopulated_fields_js.html +18 -18
  40. nautobot/core/templates/admin/submit_line.html +4 -4
  41. nautobot/core/templates/base_django.html +46 -46
  42. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +8 -8
  43. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +8 -8
  44. nautobot/core/templates/buttons/export.html +3 -3
  45. nautobot/core/templates/components/breadcrumbs.html +19 -0
  46. nautobot/core/templates/components/button/default.html +3 -3
  47. nautobot/core/templates/components/button/dropdown.html +7 -7
  48. nautobot/core/templates/components/button/formbutton.html +4 -4
  49. nautobot/core/templates/components/panel/body_content_data_table.html +1 -1
  50. nautobot/core/templates/components/panel/body_wrapper_generic_table.html +3 -0
  51. nautobot/core/templates/components/panel/footer_content_table.html +3 -1
  52. nautobot/core/templates/components/panel/header_extra_content_table.html +10 -1
  53. nautobot/core/templates/components/tab/content_wrapper.html +1 -1
  54. nautobot/core/templates/components/tab/label_wrapper.html +1 -1
  55. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +10 -3
  56. nautobot/core/templates/generic/object_bulk_add_component.html +40 -40
  57. nautobot/core/templates/generic/object_bulk_create.html +3 -3
  58. nautobot/core/templates/generic/object_bulk_destroy.html +6 -6
  59. nautobot/core/templates/generic/object_bulk_update.html +52 -52
  60. nautobot/core/templates/generic/object_changelog.html +0 -2
  61. nautobot/core/templates/generic/object_import.html +33 -33
  62. nautobot/core/templates/generic/object_list.html +271 -268
  63. nautobot/core/templates/generic/object_notes.html +0 -2
  64. nautobot/core/templates/generic/object_retrieve.html +264 -257
  65. nautobot/core/templates/graphene/graphiql.html +127 -127
  66. nautobot/core/templates/home.html +62 -62
  67. nautobot/core/templates/inc/computed_fields/panel_data.html +13 -13
  68. nautobot/core/templates/inc/created_updated.html +8 -8
  69. nautobot/core/templates/inc/custom_fields/panel_data.html +13 -13
  70. nautobot/core/templates/inc/dynamic_groups_panel.html +11 -11
  71. nautobot/core/templates/inc/footer.html +19 -19
  72. nautobot/core/templates/inc/javascript.html +1 -1
  73. nautobot/core/templates/inc/media.html +46 -46
  74. nautobot/core/templates/inc/nav_menu.html +1 -1
  75. nautobot/core/templates/inc/relationships_table_rows.html +22 -22
  76. nautobot/core/templates/inc/tenant_table_row.html +1 -1
  77. nautobot/core/templates/login.html +77 -77
  78. nautobot/core/templates/media_failure.html +38 -38
  79. nautobot/core/templates/panel_table.html +1 -1
  80. nautobot/core/templates/rest_framework/api.html +3 -3
  81. nautobot/core/templates/search.html +1 -1
  82. nautobot/core/templates/swagger_ui.html +9 -9
  83. nautobot/core/templates/utilities/confirmation_form.html +18 -18
  84. nautobot/core/templates/utilities/render_field.html +1 -1
  85. nautobot/core/templates/utilities/render_jinja2.html +43 -43
  86. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +56 -56
  87. nautobot/core/templates/utilities/templatetags/utilization_graph.html +1 -1
  88. nautobot/core/templates/utilities/theme_preview.html +799 -799
  89. nautobot/core/templates/utilities/worker_status.html +122 -122
  90. nautobot/core/templates/widgets/clearable_file.html +3 -3
  91. nautobot/core/templates/widgets/sluginput.html +1 -1
  92. nautobot/core/templatetags/buttons.py +8 -2
  93. nautobot/core/templatetags/helpers.py +24 -0
  94. nautobot/core/templatetags/ui_framework.py +40 -5
  95. nautobot/core/testing/filters.py +37 -21
  96. nautobot/core/testing/integration.py +7 -4
  97. nautobot/core/testing/views.py +49 -5
  98. nautobot/core/tests/test_breadcrumbs.py +78 -4
  99. nautobot/core/tests/test_commands.py +7 -4
  100. nautobot/core/tests/test_graphql.py +20 -5
  101. nautobot/core/tests/test_jobs.py +34 -21
  102. nautobot/core/tests/test_tables.py +43 -6
  103. nautobot/core/tests/test_templatetags_ui_framework.py +146 -0
  104. nautobot/core/tests/test_titles.py +2 -2
  105. nautobot/core/tests/test_ui.py +188 -1
  106. nautobot/core/tests/test_utils.py +35 -0
  107. nautobot/core/tests/test_views.py +45 -0
  108. nautobot/core/tests/test_views_generic.py +43 -0
  109. nautobot/core/tests/test_views_utils.py +239 -5
  110. nautobot/core/ui/breadcrumbs.py +220 -28
  111. nautobot/core/ui/bulk_buttons.py +8 -0
  112. nautobot/core/ui/object_detail.py +181 -60
  113. nautobot/core/ui/titles.py +10 -5
  114. nautobot/core/utils/requests.py +27 -2
  115. nautobot/core/views/__init__.py +24 -3
  116. nautobot/core/views/generic.py +70 -35
  117. nautobot/core/views/mixins.py +226 -122
  118. nautobot/core/views/utils.py +270 -1
  119. nautobot/dcim/api/serializers.py +8 -2
  120. nautobot/dcim/constants.py +1 -0
  121. nautobot/dcim/factory.py +4 -3
  122. nautobot/dcim/filters/mixins.py +1 -2
  123. nautobot/dcim/forms.py +5 -1
  124. nautobot/dcim/migrations/0074_alter_rack_u_height.py +21 -0
  125. nautobot/dcim/models/devices.py +30 -1
  126. nautobot/dcim/models/racks.py +2 -2
  127. nautobot/dcim/tables/__init__.py +2 -0
  128. nautobot/dcim/tables/devices.py +24 -0
  129. nautobot/dcim/tables/power.py +2 -2
  130. nautobot/dcim/templates/dcim/cable.html +53 -53
  131. nautobot/dcim/templates/dcim/cable_connect.html +182 -182
  132. nautobot/dcim/templates/dcim/cable_trace.html +1 -1
  133. nautobot/dcim/templates/dcim/console_port_connection_list.html +5 -5
  134. nautobot/dcim/templates/dcim/consoleport.html +86 -86
  135. nautobot/dcim/templates/dcim/consoleserverport.html +86 -86
  136. nautobot/dcim/templates/dcim/controller_create.html +34 -34
  137. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +68 -68
  138. nautobot/dcim/templates/dcim/device/base.html +1 -114
  139. nautobot/dcim/templates/dcim/device/config.html +17 -17
  140. nautobot/dcim/templates/dcim/device/consoleports.html +1 -52
  141. nautobot/dcim/templates/dcim/device/consoleserverports.html +1 -52
  142. nautobot/dcim/templates/dcim/device/devicebays.html +1 -48
  143. nautobot/dcim/templates/dcim/device/frontports.html +1 -52
  144. nautobot/dcim/templates/dcim/device/interfaces.html +1 -56
  145. nautobot/dcim/templates/dcim/device/inventory.html +1 -48
  146. nautobot/dcim/templates/dcim/device/lldp_neighbors.html +64 -64
  147. nautobot/dcim/templates/dcim/device/modulebays.html +1 -48
  148. nautobot/dcim/templates/dcim/device/poweroutlets.html +1 -52
  149. nautobot/dcim/templates/dcim/device/powerports.html +1 -52
  150. nautobot/dcim/templates/dcim/device/rearports.html +1 -52
  151. nautobot/dcim/templates/dcim/device/status.html +66 -66
  152. nautobot/dcim/templates/dcim/device/wireless.html +1 -72
  153. nautobot/dcim/templates/dcim/device.html +4 -422
  154. nautobot/dcim/templates/dcim/device_component.html +0 -19
  155. nautobot/dcim/templates/dcim/device_component_add.html +25 -25
  156. nautobot/dcim/templates/dcim/device_create.html +229 -0
  157. nautobot/dcim/templates/dcim/device_edit.html +2 -227
  158. nautobot/dcim/templates/dcim/devicebay.html +41 -41
  159. nautobot/dcim/templates/dcim/devicebay_populate.html +32 -32
  160. nautobot/dcim/templates/dcim/devicetype_component_add.html +28 -28
  161. nautobot/dcim/templates/dcim/devicetype_retrieve.html +1 -3
  162. nautobot/dcim/templates/dcim/frontport.html +84 -84
  163. nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +1 -1
  164. nautobot/dcim/templates/dcim/inc/device_interface_filter.html +8 -0
  165. nautobot/dcim/templates/dcim/inc/device_napalm_tabs.html +1 -15
  166. nautobot/dcim/templates/dcim/inc/location_hierarchy.html +22 -22
  167. nautobot/dcim/templates/dcim/interface.html +206 -206
  168. nautobot/dcim/templates/dcim/interface_connection_list.html +5 -5
  169. nautobot/dcim/templates/dcim/interfaceredundancygroupassociation_create.html +6 -6
  170. nautobot/dcim/templates/dcim/inventoryitem.html +44 -44
  171. nautobot/dcim/templates/dcim/inventoryitem_add.html +32 -32
  172. nautobot/dcim/templates/dcim/inventoryitem_edit.html +22 -22
  173. nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +46 -46
  174. nautobot/dcim/templates/dcim/location_retrieve.html +1 -7
  175. nautobot/dcim/templates/dcim/locationtype.html +1 -6
  176. nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -7
  177. nautobot/dcim/templates/dcim/module/base.html +85 -85
  178. nautobot/dcim/templates/dcim/module_interfaces.html +1 -1
  179. nautobot/dcim/templates/dcim/module_modulebays.html +1 -1
  180. nautobot/dcim/templates/dcim/module_retrieve.html +52 -52
  181. nautobot/dcim/templates/dcim/module_update.html +61 -61
  182. nautobot/dcim/templates/dcim/modulebay_destroy.html +1 -1
  183. nautobot/dcim/templates/dcim/modulebay_retrieve.html +83 -99
  184. nautobot/dcim/templates/dcim/modulebay_update.html +33 -33
  185. nautobot/dcim/templates/dcim/modulefamily_retrieve.html +1 -1
  186. nautobot/dcim/templates/dcim/moduletype_retrieve.html +140 -144
  187. nautobot/dcim/templates/dcim/platform_create.html +38 -38
  188. nautobot/dcim/templates/dcim/power_port_connection_list.html +5 -5
  189. nautobot/dcim/templates/dcim/powerfeed_retrieve.html +1 -8
  190. nautobot/dcim/templates/dcim/poweroutlet.html +85 -85
  191. nautobot/dcim/templates/dcim/powerpanel_retrieve.html +1 -8
  192. nautobot/dcim/templates/dcim/powerport.html +91 -91
  193. nautobot/dcim/templates/dcim/rack_elevation_list.html +18 -18
  194. nautobot/dcim/templates/dcim/rack_retrieve.html +264 -274
  195. nautobot/dcim/templates/dcim/rackreservation_retrieve.html +0 -3
  196. nautobot/dcim/templates/dcim/rearport.html +78 -78
  197. nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +1 -50
  198. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -5
  199. nautobot/dcim/tests/integration/test_device_bulk_operations.py +3 -2
  200. nautobot/dcim/tests/integration/test_location_bulk_operations.py +6 -2
  201. nautobot/dcim/tests/test_api.py +33 -1
  202. nautobot/dcim/tests/test_views.py +189 -4
  203. nautobot/dcim/ui.py +29 -0
  204. nautobot/dcim/urls.py +1 -109
  205. nautobot/dcim/utils.py +30 -0
  206. nautobot/dcim/views.py +1149 -550
  207. nautobot/extras/filters/mixins.py +1 -1
  208. nautobot/extras/forms/forms.py +15 -0
  209. nautobot/extras/models/groups.py +10 -1
  210. nautobot/extras/models/jobs.py +2 -2
  211. nautobot/extras/plugins/views.py +18 -5
  212. nautobot/extras/tables.py +24 -2
  213. nautobot/extras/templates/extras/computedfield_edit.html +4 -4
  214. nautobot/extras/templates/extras/configcontext_update.html +1 -1
  215. nautobot/extras/templates/extras/configcontextschema_retrieve.html +32 -32
  216. nautobot/extras/templates/extras/customfield_retrieve.html +1 -128
  217. nautobot/extras/templates/extras/customfield_update.html +23 -23
  218. nautobot/extras/templates/extras/dynamicgroup.html +2 -99
  219. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -199
  220. nautobot/extras/templates/extras/dynamicgroup_retrieve.html +99 -0
  221. nautobot/extras/templates/extras/dynamicgroup_update.html +199 -0
  222. nautobot/extras/templates/extras/gitrepository.html +2 -82
  223. nautobot/extras/templates/extras/gitrepository_list.html +10 -10
  224. nautobot/extras/templates/extras/gitrepository_object_edit.html +2 -13
  225. nautobot/extras/templates/extras/gitrepository_retrieve.html +82 -0
  226. nautobot/extras/templates/extras/gitrepository_update.html +13 -0
  227. nautobot/extras/templates/extras/graphqlquery_retrieve.html +73 -73
  228. nautobot/extras/templates/extras/inc/configcontext_format.html +2 -2
  229. nautobot/extras/templates/extras/inc/job_table.html +10 -10
  230. nautobot/extras/templates/extras/inc/jobresult.html +21 -21
  231. nautobot/extras/templates/extras/inc/jobresult_js.html +6 -6
  232. nautobot/extras/templates/extras/inc/tags_panel.html +10 -10
  233. nautobot/extras/templates/extras/job.html +64 -64
  234. nautobot/extras/templates/extras/job_approval_request.html +9 -9
  235. nautobot/extras/templates/extras/job_bulk_edit.html +13 -13
  236. nautobot/extras/templates/extras/job_edit.html +45 -45
  237. nautobot/extras/templates/extras/job_list.html +4 -4
  238. nautobot/extras/templates/extras/jobresult_retrieve.html +0 -25
  239. nautobot/extras/templates/extras/marketplace.html +101 -101
  240. nautobot/extras/templates/extras/metadatatype_create.html +20 -20
  241. nautobot/extras/templates/extras/note_retrieve.html +0 -52
  242. nautobot/extras/templates/extras/object_assign_contact_or_team.html +18 -18
  243. nautobot/extras/templates/extras/object_configcontext.html +1 -3
  244. nautobot/extras/templates/extras/objectchange.html +2 -165
  245. nautobot/extras/templates/extras/objectchange_retrieve.html +165 -0
  246. nautobot/extras/templates/extras/plugin_detail.html +44 -48
  247. nautobot/extras/templates/extras/plugins_list.html +9 -11
  248. nautobot/extras/templates/extras/plugins_tiles.html +26 -26
  249. nautobot/extras/templates/extras/relationship_edit.html +4 -4
  250. nautobot/extras/templates/extras/role_retrieve.html +13 -13
  251. nautobot/extras/templates/extras/scheduled_jobs_approval_queue_list.html +21 -21
  252. nautobot/extras/templates/extras/scheduledjob.html +128 -128
  253. nautobot/extras/templates/extras/secret_create.html +53 -53
  254. nautobot/extras/templates/extras/secretsgroup_update.html +13 -13
  255. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +3 -3
  256. nautobot/extras/templates/extras/webhook.html +79 -79
  257. nautobot/extras/tests/integration/test_relationships.py +6 -6
  258. nautobot/extras/tests/test_dynamicgroups.py +73 -18
  259. nautobot/extras/tests/test_filters.py +1 -1
  260. nautobot/extras/tests/test_jobs.py +2 -0
  261. nautobot/extras/tests/test_views.py +8 -3
  262. nautobot/extras/urls.py +3 -97
  263. nautobot/extras/views.py +524 -456
  264. nautobot/ipam/filters.py +2 -2
  265. nautobot/ipam/migrations/0053_alter_vrfdeviceassignment_options_and_more.py +20 -0
  266. nautobot/ipam/models.py +34 -0
  267. nautobot/ipam/querysets.py +3 -3
  268. nautobot/ipam/signals.py +6 -1
  269. nautobot/ipam/tables.py +3 -1
  270. nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +4 -0
  271. nautobot/ipam/templates/ipam/inc/toggle_available.html +8 -8
  272. nautobot/ipam/templates/ipam/inc/vlangroup_header.html +4 -4
  273. nautobot/ipam/templates/ipam/ipaddress.html +119 -123
  274. nautobot/ipam/templates/ipam/ipaddress_assign.html +10 -10
  275. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -1
  276. nautobot/ipam/templates/ipam/ipaddress_merge.html +180 -180
  277. nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +48 -48
  278. nautobot/ipam/templates/ipam/prefix.html +2 -115
  279. nautobot/ipam/templates/ipam/prefix_create.html +34 -0
  280. nautobot/ipam/templates/ipam/prefix_edit.html +1 -34
  281. nautobot/ipam/templates/ipam/prefix_retrieve.html +3 -0
  282. nautobot/ipam/templates/ipam/service_retrieve.html +1 -6
  283. nautobot/ipam/templates/ipam/vlan_retrieve.html +1 -7
  284. nautobot/ipam/templates/ipam/vrf_edit.html +1 -1
  285. nautobot/ipam/tests/test_api.py +5 -0
  286. nautobot/ipam/tests/test_models.py +387 -0
  287. nautobot/ipam/tests/test_querysets.py +46 -0
  288. nautobot/ipam/tests/test_views.py +34 -0
  289. nautobot/ipam/ui.py +145 -0
  290. nautobot/ipam/urls.py +1 -46
  291. nautobot/ipam/utils/__init__.py +26 -0
  292. nautobot/ipam/utils/migrations.py +1 -1
  293. nautobot/ipam/views.py +234 -112
  294. nautobot/project-static/docs/404.html +11 -11
  295. nautobot/project-static/docs/apps/index.html +11 -11
  296. nautobot/project-static/docs/apps/nautobot-apps.html +11 -11
  297. nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js → bundle.f55a23d4.min.js} +2 -2
  298. nautobot/project-static/docs/assets/javascripts/{bundle.92b07e13.min.js.map → bundle.f55a23d4.min.js.map} +2 -2
  299. nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css → main.e53b48f4.min.css} +1 -1
  300. nautobot/project-static/docs/assets/stylesheets/{main.7e37652d.min.css.map → main.e53b48f4.min.css.map} +1 -1
  301. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +11 -11
  302. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +11 -11
  303. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +11 -11
  304. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +11 -11
  305. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +11 -11
  306. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +11 -11
  307. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +11 -11
  308. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +11 -11
  309. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +11 -11
  310. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +11 -11
  311. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +11 -11
  312. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +11 -11
  313. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +11 -11
  314. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +11 -11
  315. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +11 -11
  316. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +11 -11
  317. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +11 -11
  318. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +11 -11
  319. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +11 -11
  320. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +83 -11
  321. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1265 -281
  322. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +11 -11
  323. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +12 -12
  324. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +452 -29
  325. nautobot/project-static/docs/development/apps/api/configuration-view.html +11 -11
  326. nautobot/project-static/docs/development/apps/api/database-backend-config.html +11 -11
  327. nautobot/project-static/docs/development/apps/api/models/django-admin.html +11 -11
  328. nautobot/project-static/docs/development/apps/api/models/global-search.html +11 -11
  329. nautobot/project-static/docs/development/apps/api/models/graphql.html +11 -11
  330. nautobot/project-static/docs/development/apps/api/models/index.html +11 -11
  331. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +12 -12
  332. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +11 -11
  333. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +11 -11
  334. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +11 -11
  335. nautobot/project-static/docs/development/apps/api/platform-features/index.html +11 -11
  336. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +11 -11
  337. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +11 -11
  338. nautobot/project-static/docs/development/apps/api/platform-features/prepopulating-data.html +11 -11
  339. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +11 -11
  340. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +11 -11
  341. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +11 -11
  342. nautobot/project-static/docs/development/apps/api/prometheus.html +11 -11
  343. nautobot/project-static/docs/development/apps/api/setup.html +11 -11
  344. nautobot/project-static/docs/development/apps/api/testing.html +11 -11
  345. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +11 -11
  346. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +11 -11
  347. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +11 -11
  348. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +11 -11
  349. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +11 -11
  350. nautobot/project-static/docs/development/apps/api/views/base-template.html +11 -11
  351. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +11 -11
  352. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +11 -11
  353. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +11 -11
  354. nautobot/project-static/docs/development/apps/api/views/index.html +11 -11
  355. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +11 -11
  356. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +11 -11
  357. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +11 -11
  358. nautobot/project-static/docs/development/apps/api/views/notes.html +11 -11
  359. nautobot/project-static/docs/development/apps/api/views/rest-api.html +11 -11
  360. nautobot/project-static/docs/development/apps/api/views/urls.html +11 -11
  361. nautobot/project-static/docs/development/apps/index.html +11 -11
  362. nautobot/project-static/docs/development/apps/migration/code-updates.html +11 -11
  363. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +11 -11
  364. nautobot/project-static/docs/development/apps/migration/from-v1.html +11 -11
  365. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +11 -11
  366. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +11 -11
  367. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +11 -11
  368. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +11 -11
  369. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +11 -11
  370. nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +11 -11
  371. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +11 -11
  372. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +11 -11
  373. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +11 -11
  374. nautobot/project-static/docs/development/apps/porting-from-netbox.html +11 -11
  375. nautobot/project-static/docs/development/core/application-registry.html +11 -11
  376. nautobot/project-static/docs/development/core/best-practices.html +11 -11
  377. nautobot/project-static/docs/development/core/bootstrap-ui.html +11 -11
  378. nautobot/project-static/docs/development/core/caching.html +11 -11
  379. nautobot/project-static/docs/development/core/controllers.html +11 -11
  380. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +11 -11
  381. nautobot/project-static/docs/development/core/generic-views.html +11 -11
  382. nautobot/project-static/docs/development/core/getting-started.html +50 -63
  383. nautobot/project-static/docs/development/core/homepage.html +11 -11
  384. nautobot/project-static/docs/development/core/index.html +11 -11
  385. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +11 -11
  386. nautobot/project-static/docs/development/core/model-checklist.html +11 -11
  387. nautobot/project-static/docs/development/core/model-features.html +11 -11
  388. nautobot/project-static/docs/development/core/natural-keys.html +11 -11
  389. nautobot/project-static/docs/development/core/navigation-menu.html +11 -11
  390. nautobot/project-static/docs/development/core/release-checklist.html +11 -11
  391. nautobot/project-static/docs/development/core/role-internals.html +11 -11
  392. nautobot/project-static/docs/development/core/settings.html +11 -11
  393. nautobot/project-static/docs/development/core/style-guide.html +15 -11
  394. nautobot/project-static/docs/development/core/templates.html +11 -11
  395. nautobot/project-static/docs/development/core/testing.html +11 -11
  396. nautobot/project-static/docs/development/core/ui-component-framework.html +17 -22
  397. nautobot/project-static/docs/development/core/user-preferences.html +11 -11
  398. nautobot/project-static/docs/development/index.html +11 -11
  399. nautobot/project-static/docs/development/jobs/getting-started.html +11 -11
  400. nautobot/project-static/docs/development/jobs/index.html +11 -11
  401. nautobot/project-static/docs/development/jobs/installation.html +11 -11
  402. nautobot/project-static/docs/development/jobs/job-extensions.html +11 -11
  403. nautobot/project-static/docs/development/jobs/job-logging.html +11 -11
  404. nautobot/project-static/docs/development/jobs/job-patterns.html +11 -11
  405. nautobot/project-static/docs/development/jobs/job-structure.html +11 -11
  406. nautobot/project-static/docs/development/jobs/migration/from-v1.html +11 -11
  407. nautobot/project-static/docs/development/jobs/testing.html +11 -11
  408. nautobot/project-static/docs/index.html +11 -11
  409. nautobot/project-static/docs/objects.inv +0 -0
  410. nautobot/project-static/docs/overview/application_stack.html +11 -11
  411. nautobot/project-static/docs/overview/design_philosophy.html +11 -11
  412. nautobot/project-static/docs/release-notes/index.html +11 -11
  413. nautobot/project-static/docs/release-notes/version-1.0.html +11 -11
  414. nautobot/project-static/docs/release-notes/version-1.1.html +11 -11
  415. nautobot/project-static/docs/release-notes/version-1.2.html +11 -11
  416. nautobot/project-static/docs/release-notes/version-1.3.html +11 -11
  417. nautobot/project-static/docs/release-notes/version-1.4.html +11 -11
  418. nautobot/project-static/docs/release-notes/version-1.5.html +11 -11
  419. nautobot/project-static/docs/release-notes/version-1.6.html +11 -11
  420. nautobot/project-static/docs/release-notes/version-2.0.html +11 -11
  421. nautobot/project-static/docs/release-notes/version-2.1.html +11 -11
  422. nautobot/project-static/docs/release-notes/version-2.2.html +11 -11
  423. nautobot/project-static/docs/release-notes/version-2.3.html +11 -11
  424. nautobot/project-static/docs/release-notes/version-2.4.html +418 -11
  425. nautobot/project-static/docs/search/search_index.json +1 -1
  426. nautobot/project-static/docs/sitemap.xml +300 -300
  427. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  428. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +11 -11
  429. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +11 -11
  430. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +11 -11
  431. nautobot/project-static/docs/user-guide/administration/configuration/index.html +11 -11
  432. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +11 -11
  433. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +38 -11
  434. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +11 -11
  435. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +89 -14
  436. nautobot/project-static/docs/user-guide/administration/guides/docker.html +11 -11
  437. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +11 -11
  438. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +11 -11
  439. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +11 -11
  440. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +11 -11
  441. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +11 -11
  442. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +11 -11
  443. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +11 -11
  444. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +11 -11
  445. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +11 -11
  446. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +11 -11
  447. nautobot/project-static/docs/user-guide/administration/installation/index.html +11 -11
  448. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +11 -11
  449. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +11 -11
  450. nautobot/project-static/docs/user-guide/administration/installation/services.html +11 -11
  451. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +11 -11
  452. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +11 -11
  453. nautobot/project-static/docs/user-guide/administration/security/index.html +11 -11
  454. nautobot/project-static/docs/user-guide/administration/security/notices.html +11 -11
  455. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +11 -11
  456. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +11 -11
  457. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +11 -11
  458. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +11 -11
  459. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +11 -11
  460. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +11 -11
  461. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +11 -11
  462. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +11 -11
  463. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +11 -11
  464. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +11 -11
  465. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +11 -11
  466. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +11 -11
  467. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +11 -11
  468. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +11 -11
  469. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +11 -11
  470. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +11 -11
  471. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +11 -11
  472. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +11 -11
  473. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +11 -11
  474. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +11 -11
  475. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +11 -11
  476. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +11 -11
  477. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +11 -11
  478. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +11 -11
  479. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +11 -11
  480. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +11 -11
  481. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +11 -11
  482. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +11 -11
  483. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +11 -11
  484. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +11 -11
  485. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +11 -11
  486. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +11 -11
  487. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +11 -11
  488. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +11 -11
  489. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +11 -11
  490. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +11 -11
  491. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +11 -11
  492. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +11 -11
  493. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +11 -11
  494. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +11 -11
  495. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +11 -11
  496. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +11 -11
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +11 -11
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +11 -11
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +11 -11
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +11 -11
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +11 -11
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +11 -11
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +11 -11
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +11 -11
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +11 -11
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +11 -11
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +11 -11
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +11 -11
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +11 -11
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +11 -11
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +11 -11
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +11 -11
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +11 -11
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +11 -11
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +11 -11
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +11 -11
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +11 -11
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +11 -11
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +11 -11
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +11 -11
  521. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +11 -11
  522. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +11 -11
  523. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +11 -11
  524. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +11 -11
  525. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +11 -11
  526. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +11 -11
  527. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +11 -11
  528. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +11 -11
  529. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +11 -11
  530. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +11 -11
  531. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +11 -11
  532. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +11 -11
  533. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +11 -11
  534. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +11 -11
  535. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +11 -11
  536. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +11 -11
  537. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +11 -11
  538. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +11 -11
  539. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +11 -11
  540. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +11 -11
  541. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +11 -11
  542. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +11 -11
  543. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +11 -11
  544. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +11 -11
  545. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +11 -11
  546. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -11
  547. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +11 -11
  548. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +11 -11
  549. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +11 -11
  550. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +11 -11
  551. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +11 -11
  552. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +11 -11
  553. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +11 -11
  554. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +11 -11
  555. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +11 -11
  556. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +11 -11
  557. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +11 -11
  558. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +11 -11
  559. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +11 -11
  560. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +11 -11
  561. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +11 -11
  562. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +11 -11
  563. nautobot/project-static/docs/user-guide/index.html +11 -11
  564. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +11 -11
  565. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +11 -11
  566. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +11 -11
  567. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +11 -11
  568. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +11 -11
  569. nautobot/project-static/docs/user-guide/platform-functionality/events.html +11 -11
  570. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +11 -11
  571. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +11 -11
  572. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +11 -11
  573. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +11 -11
  574. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +11 -11
  575. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +11 -11
  576. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +11 -11
  577. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +11 -11
  578. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +11 -11
  579. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +11 -11
  580. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +11 -11
  581. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +11 -11
  582. nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +11 -11
  583. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +11 -11
  584. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +11 -11
  585. nautobot/project-static/docs/user-guide/platform-functionality/note.html +11 -11
  586. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +11 -11
  587. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +11 -11
  588. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +11 -11
  589. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +11 -11
  590. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +11 -11
  591. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +11 -11
  592. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +11 -11
  593. nautobot/project-static/docs/user-guide/platform-functionality/role.html +11 -11
  594. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +11 -11
  595. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +11 -11
  596. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +11 -11
  597. nautobot/project-static/docs/user-guide/platform-functionality/status.html +11 -11
  598. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +11 -11
  599. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +11 -11
  600. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +11 -11
  601. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +11 -11
  602. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +11 -11
  603. nautobot/project-static/img/nautobot_icon.svg +32 -34
  604. nautobot/project-static/js/table_sorting_indicator.js +0 -2
  605. nautobot/tenancy/templates/tenancy/tenant.html +1 -7
  606. nautobot/tenancy/views.py +13 -0
  607. nautobot/users/templates/users/api_tokens.html +4 -4
  608. nautobot/users/templates/users/base.html +28 -28
  609. nautobot/virtualization/templates/virtualization/cluster.html +64 -64
  610. nautobot/virtualization/templates/virtualization/inc/virtualmachine_vminterface_filter.html +8 -0
  611. nautobot/virtualization/templates/virtualization/virtualmachine_component_add.html +25 -25
  612. nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +1 -251
  613. nautobot/virtualization/templates/virtualization/vminterface.html +70 -70
  614. nautobot/virtualization/urls.py +0 -12
  615. nautobot/virtualization/views.py +158 -54
  616. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +13 -13
  617. nautobot/wireless/tests/integration/test_radio_profile.py +1 -1
  618. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/METADATA +4 -4
  619. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/RECORD +623 -607
  620. nautobot/core/templates/inc/breadcrumbs.html +0 -14
  621. nautobot/ipam/templates/ipam/prefix_ipaddresses.html +0 -11
  622. nautobot/ipam/templates/ipam/prefix_prefixes.html +0 -11
  623. nautobot/project-static/docs/requirements.txt +0 -14
  624. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/LICENSE.txt +0 -0
  625. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/NOTICE +0 -0
  626. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/WHEEL +0 -0
  627. {nautobot-2.4.17.dist-info → nautobot-2.4.19.dist-info}/entry_points.txt +0 -0
@@ -7,7 +7,9 @@ from django.contrib.auth import get_user_model
7
7
  from django.contrib.contenttypes.models import ContentType
8
8
  from django.db.models import Q
9
9
  from django.test import override_settings
10
+ from django.test.client import RequestFactory
10
11
  from django.urls import reverse
12
+ from django.utils.html import strip_spaces_between_tags
11
13
  from netaddr import EUI
12
14
  import yaml
13
15
 
@@ -107,6 +109,7 @@ from nautobot.dcim.models import (
107
109
  from nautobot.dcim.views import (
108
110
  ConsoleConnectionsListView,
109
111
  InterfaceConnectionsListView,
112
+ LocationUIViewSet,
110
113
  PowerConnectionsListView,
111
114
  )
112
115
  from nautobot.extras.choices import CustomFieldTypeChoices, RelationshipTypeChoices
@@ -208,6 +211,8 @@ class LocationTypeTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewT
208
211
 
209
212
  class LocationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
210
213
  model = Location
214
+ # One query for the natural slug, one for `LocationViewSet.get_extra_context`
215
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 2}
211
216
 
212
217
  @classmethod
213
218
  def setUpTestData(cls):
@@ -230,7 +235,14 @@ class LocationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
230
235
  status=status,
231
236
  description="Hi!",
232
237
  )
233
- for loc in [loc1, loc2, loc3, loc4]:
238
+ loc5 = Location.objects.create(
239
+ name="Leaf 2",
240
+ location_type=lt3,
241
+ parent=loc3,
242
+ status=status,
243
+ description="Hi!",
244
+ )
245
+ for loc in [loc1, loc2, loc3, loc4, loc5]:
234
246
  loc.validated_save()
235
247
 
236
248
  cls.form_data = {
@@ -429,10 +441,28 @@ class LocationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
429
441
  self.assertEqual(location.contact_phone, "")
430
442
  self.assertEqual(location.contact_email, "")
431
443
 
444
+ def test_get_extra_context(self):
445
+ view_set = LocationUIViewSet()
446
+ child_1, child_2 = Location.objects.filter(name__startswith="Leaf ")
447
+ parent_location = child_1.parent
448
+ child_1.location_type.content_types.add(ContentType.objects.get_for_model(Prefix))
449
+ status = Status.objects.get_for_model(Prefix).first()
450
+ prefix_1 = Prefix.objects.create(network="192.0.2.0", prefix_length=25, status=status)
451
+ prefix_2 = Prefix.objects.create(network="192.0.2.128", prefix_length=25, status=status)
452
+ prefix_1.locations.set([child_1, child_2])
453
+ prefix_2.locations.set([child_1, child_2])
454
+ request = RequestFactory().get(parent_location.get_absolute_url())
455
+ request.user = self.user
456
+ self.add_permissions("dcim.view_location")
457
+ self.add_permissions("ipam.view_prefix")
458
+ context = view_set.get_extra_context(request=request, instance=parent_location)
459
+ self.assertEqual(context["stats"]["prefix_count"], 2)
460
+
432
461
 
433
462
  class RackGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTestCases.BulkEditObjectsViewTestCase):
434
463
  model = RackGroup
435
464
  sort_on_field = "name"
465
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
436
466
 
437
467
  @classmethod
438
468
  def setUpTestData(cls):
@@ -460,6 +490,7 @@ class RackGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTest
460
490
 
461
491
  class RackReservationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
462
492
  model = RackReservation
493
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
463
494
 
464
495
  @classmethod
465
496
  def setUpTestData(cls):
@@ -495,6 +526,7 @@ class RackReservationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
495
526
 
496
527
  class RackTestCase(ViewTestCases.PrimaryObjectViewTestCase):
497
528
  model = Rack
529
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
498
530
 
499
531
  @classmethod
500
532
  def setUpTestData(cls):
@@ -2081,6 +2113,7 @@ class PlatformTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTestC
2081
2113
 
2082
2114
  class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2083
2115
  model = Device
2116
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2084
2117
 
2085
2118
  @classmethod
2086
2119
  def setUpTestData(cls):
@@ -2278,6 +2311,7 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2278
2311
  def test_vdc_panel_includes_add_vdc_btn(self):
2279
2312
  """Assert Add Virtual device Contexts button is in Device detail view: Issue from #6348"""
2280
2313
  device = Device.objects.first()
2314
+ self.add_permissions("dcim.add_virtualdevicecontext")
2281
2315
  url = reverse("dcim:device", kwargs={"pk": device.pk})
2282
2316
  response = self.client.get(url)
2283
2317
  response_body = extract_page_body(response.content.decode(response.charset))
@@ -2292,6 +2326,63 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2292
2326
  self.assertInHTML(expected_add_vdc_button_html, response_body)
2293
2327
  self.assertIn("Add virtual device context", response_body)
2294
2328
 
2329
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2330
+ def test_device_detail_with_parent_bay(self):
2331
+ parent_device = Device.objects.first()
2332
+ parent_device.subdevice_role = "parent"
2333
+ parent_device.validated_save()
2334
+ child_device = Device.objects.last()
2335
+ child_device.location = parent_device.location
2336
+ child_device.subdevice_role = "child"
2337
+ child_device.validated_save()
2338
+ device_bay = DeviceBay.objects.create(
2339
+ name="test device bay", device=parent_device, installed_device=child_device
2340
+ )
2341
+
2342
+ url = reverse("dcim:device", kwargs={"pk": child_device.pk})
2343
+ response = self.client.get(url)
2344
+ self.assertHttpStatus(response, 200)
2345
+ response_body = extract_page_body(response.content.decode(response.charset))
2346
+ self.assertInHTML(parent_device.display, response_body)
2347
+ self.assertInHTML(str(device_bay), response_body)
2348
+
2349
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2350
+ def test_device_detail_with_rack(self):
2351
+ device = Device.objects.filter(device_type__u_height__gt=0).first()
2352
+ self.assertIsNotNone(device)
2353
+ device.rack = Rack.objects.filter(u_height__gt=device.device_type.u_height).first()
2354
+ self.assertIsNotNone(device.rack)
2355
+ device.position = 1
2356
+ device.face = "front"
2357
+ device.validated_save()
2358
+ url = reverse("dcim:device", kwargs={"pk": device.pk})
2359
+ response = self.client.get(url)
2360
+ self.assertHttpStatus(response, 200)
2361
+ response_body = extract_page_body(response.content.decode(response.charset))
2362
+ self.assertInHTML(f"U{device.position} / {device.get_face_display()}", response_body)
2363
+
2364
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2365
+ def test_device_modulebays(self):
2366
+ device = Device.objects.filter(module_bays__isnull=True).first()
2367
+ module = Module.objects.filter(parent_module_bay__isnull=True).first()
2368
+
2369
+ module_bays = (
2370
+ ModuleBay.objects.create(parent_device=device, name="Test View Module Bay 1"),
2371
+ ModuleBay.objects.create(parent_device=device, name="Test View Module Bay 2"),
2372
+ ModuleBay.objects.create(parent_device=device, name="Test View Module Bay 3"),
2373
+ )
2374
+
2375
+ module.location = None
2376
+ module.parent_module_bay = module_bays[0]
2377
+ module.validated_save()
2378
+
2379
+ url = reverse("dcim:device_modulebays", kwargs={"pk": device.pk})
2380
+ response = self.client.get(url)
2381
+ self.assertHttpStatus(response, 200)
2382
+ # Custom badge - module count / module-bay count
2383
+ response_body = extract_page_body(response.content.decode(response.charset))
2384
+ self.assertInHTML("1/3", response_body)
2385
+
2295
2386
  @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2296
2387
  def test_device_consoleports(self):
2297
2388
  device = Device.objects.first()
@@ -2491,6 +2582,32 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2491
2582
  url = reverse("dcim:device_inventory", kwargs={"pk": device.pk})
2492
2583
  self.assertHttpStatus(self.client.get(url), 200)
2493
2584
 
2585
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2586
+ def test_device_wireless(self):
2587
+ self.add_permissions("dcim.view_controllermanageddevicegroup")
2588
+ device = Device.objects.first()
2589
+ device.controller_managed_device_group = ControllerManagedDeviceGroup.objects.first()
2590
+ device.validated_save()
2591
+ device.controller_managed_device_group.capabilities = ["wireless"]
2592
+ device.controller_managed_device_group.validated_save()
2593
+
2594
+ url = reverse("dcim:device_wireless", kwargs={"pk": device.pk})
2595
+ response = self.client.get(url)
2596
+ self.assertHttpStatus(response, 200)
2597
+
2598
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2599
+ def test_device_napalm_tabs(self):
2600
+ self.add_permissions("dcim.napalm_read_device")
2601
+ device = Device.objects.first()
2602
+ # TODO set NAPALM args, mock NAPALM APIs?
2603
+
2604
+ url = reverse("dcim:device_status", kwargs={"pk": device.pk})
2605
+ self.assertHttpStatus(self.client.get(url), 200)
2606
+ url = reverse("dcim:device_lldp_neighbors", kwargs={"pk": device.pk})
2607
+ self.assertHttpStatus(self.client.get(url), 200)
2608
+ url = reverse("dcim:device_config", kwargs={"pk": device.pk})
2609
+ self.assertHttpStatus(self.client.get(url), 200)
2610
+
2494
2611
  @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2495
2612
  def test_device_primary_ips(self):
2496
2613
  """Test assigning a primary IP to a device."""
@@ -2543,6 +2660,13 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2543
2660
  schema.pk,
2544
2661
  )
2545
2662
 
2663
+ url = reverse("dcim:device_configcontext", kwargs={"pk": self._get_queryset().get(name="Device X").pk})
2664
+ response = self.client.get(url)
2665
+ self.assertHttpStatus(response, 200)
2666
+ response_body = extract_page_body(response.content.decode(response.charset))
2667
+ self.assertIn("foo", response_body)
2668
+ self.assertIn("bar", response_body)
2669
+
2546
2670
  @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
2547
2671
  def test_local_config_context_schema_validation_fails(self):
2548
2672
  """
@@ -2773,6 +2897,7 @@ class ModuleTestCase(ViewTestCases.PrimaryObjectViewTestCase):
2773
2897
 
2774
2898
  class ConsolePortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2775
2899
  model = ConsolePort
2900
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2776
2901
 
2777
2902
  @classmethod
2778
2903
  def setUpTestData(cls):
@@ -2822,6 +2947,7 @@ class ConsolePortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2822
2947
 
2823
2948
  class ConsoleServerPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2824
2949
  model = ConsoleServerPort
2950
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2825
2951
 
2826
2952
  @classmethod
2827
2953
  def setUpTestData(cls):
@@ -2870,6 +2996,7 @@ class ConsoleServerPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2870
2996
 
2871
2997
  class PowerPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2872
2998
  model = PowerPort
2999
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2873
3000
 
2874
3001
  @classmethod
2875
3002
  def setUpTestData(cls):
@@ -2926,6 +3053,7 @@ class PowerPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
2926
3053
 
2927
3054
  class PowerOutletTestCase(ViewTestCases.DeviceComponentViewTestCase):
2928
3055
  model = PowerOutlet
3056
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2929
3057
 
2930
3058
  @classmethod
2931
3059
  def setUpTestData(cls):
@@ -2995,6 +3123,7 @@ class PowerOutletTestCase(ViewTestCases.DeviceComponentViewTestCase):
2995
3123
 
2996
3124
  class InterfaceTestCase(ViewTestCases.DeviceComponentViewTestCase):
2997
3125
  model = Interface
3126
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
2998
3127
 
2999
3128
  @classmethod
3000
3129
  def setUpTestData(cls):
@@ -3195,6 +3324,7 @@ class InterfaceTestCase(ViewTestCases.DeviceComponentViewTestCase):
3195
3324
 
3196
3325
  class FrontPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
3197
3326
  model = FrontPort
3327
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
3198
3328
 
3199
3329
  @classmethod
3200
3330
  def setUpTestData(cls):
@@ -3310,6 +3440,7 @@ class FrontPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
3310
3440
 
3311
3441
  class RearPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
3312
3442
  model = RearPort
3443
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
3313
3444
 
3314
3445
  @classmethod
3315
3446
  def setUpTestData(cls):
@@ -3376,6 +3507,7 @@ class RearPortTestCase(ViewTestCases.DeviceComponentViewTestCase):
3376
3507
 
3377
3508
  class DeviceBayTestCase(ViewTestCases.DeviceComponentViewTestCase):
3378
3509
  model = DeviceBay
3510
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
3379
3511
 
3380
3512
  @classmethod
3381
3513
  def setUpTestData(cls):
@@ -4185,7 +4317,11 @@ class VirtualChassisTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4185
4317
  Interface.objects.create(device=self.devices[0], name="eth0", status=interface_status)
4186
4318
  Interface.objects.create(device=self.devices[0], name="eth1", status=interface_status)
4187
4319
  response = self.client.get(reverse("dcim:device_interfaces", kwargs={"pk": self.devices[0].pk}))
4188
- self.assertBodyContains(response, "<th>Device</th>", html=True)
4320
+ self.assertBodyContains(
4321
+ response,
4322
+ '<th class="orderable"><a data-column-name="device" href="?sort=device">Device</a></th>',
4323
+ html=True,
4324
+ )
4189
4325
 
4190
4326
  def test_device_column_not_visible(self):
4191
4327
  """
@@ -4198,13 +4334,60 @@ class VirtualChassisTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4198
4334
  Interface.objects.create(device=self.devices[1], name="eth2", status=interface_status)
4199
4335
  Interface.objects.create(device=self.devices[1], name="eth3", status=interface_status)
4200
4336
  response = self.client.get(reverse("dcim:device_interfaces", kwargs={"pk": self.devices[1].pk}))
4201
- self.assertNotIn("<th >Device</th>", extract_page_body(response.content.decode(response.charset)))
4337
+ self.assertNotIn(
4338
+ '<th class="orderable"><a data-column-name="device" href="?sort=device">Device</a></th>',
4339
+ strip_spaces_between_tags(extract_page_body(response.content.decode(response.charset))),
4340
+ )
4202
4341
  # Sanity check:
4203
- self.assertBodyContains(response, "<th>Name</th>", html=True)
4342
+ self.assertBodyContains(
4343
+ response, '<th class="orderable"><a data-column-name="name" href="?sort=name">Name</a></th>', html=True
4344
+ )
4345
+
4346
+ def test_set_master_after_adding_member(self):
4347
+ """Ensure master can be set for a member that was added via the Add Member flow."""
4348
+ self.add_permissions(
4349
+ "dcim.view_device",
4350
+ "dcim.view_virtualchassis",
4351
+ "dcim.change_virtualchassis",
4352
+ "dcim.change_device",
4353
+ )
4354
+
4355
+ # Create VC
4356
+ vc = VirtualChassis.objects.create(name="VC-test", domain="domain-test")
4357
+
4358
+ # Simulate adding a member via the separate "add-member" flow by creating the device with virtual_chassis
4359
+ member = Device.objects.create(
4360
+ device_type=self.devices[0].device_type,
4361
+ role=self.devices[0].role,
4362
+ status=self.devices[0].status,
4363
+ name="separately-added-device",
4364
+ location=self.devices[0].location,
4365
+ virtual_chassis=vc,
4366
+ vc_position=1,
4367
+ )
4368
+
4369
+ # Now edit the VC and set the master to the existing member
4370
+ payload_data = {
4371
+ "name": vc.name,
4372
+ "domain": vc.domain,
4373
+ "master": str(member.pk),
4374
+ # no members formset rows are required because the member already exists
4375
+ "form-TOTAL_FORMS": "0",
4376
+ "form-INITIAL_FORMS": "0",
4377
+ "form-MIN_NUM_FORMS": "0",
4378
+ "form-MAX_NUM_FORMS": "1000",
4379
+ }
4380
+
4381
+ url = reverse("dcim:virtualchassis_edit", kwargs={"pk": vc.pk})
4382
+ self.client.post(url, data=payload_data, follow=True)
4383
+
4384
+ vc.refresh_from_db()
4385
+ self.assertEqual(vc.master, member)
4204
4386
 
4205
4387
 
4206
4388
  class PowerPanelTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4207
4389
  model = PowerPanel
4390
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
4208
4391
 
4209
4392
  @classmethod
4210
4393
  def setUpTestData(cls):
@@ -4233,6 +4416,7 @@ class PowerPanelTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4233
4416
 
4234
4417
  class PowerFeedTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4235
4418
  model = PowerFeed
4419
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
4236
4420
 
4237
4421
  @classmethod
4238
4422
  def setUpTestData(cls):
@@ -4672,6 +4856,7 @@ class ControllerManagedDeviceGroupTestCase(ViewTestCases.PrimaryObjectViewTestCa
4672
4856
  class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
4673
4857
  model = VirtualDeviceContext
4674
4858
  filterset = VirtualDeviceContextFilterSet
4859
+ allowed_number_of_tree_queries_per_view_type = {"retrieve": 1}
4675
4860
 
4676
4861
  @classmethod
4677
4862
  def setUpTestData(cls):
nautobot/dcim/ui.py ADDED
@@ -0,0 +1,29 @@
1
+ from django.template import Context
2
+
3
+ from nautobot.core.ui.breadcrumbs import (
4
+ AncestorsBreadcrumbs,
5
+ InstanceBreadcrumbItem,
6
+ InstanceParentBreadcrumbItem,
7
+ ModelBreadcrumbItem,
8
+ )
9
+ from nautobot.core.views.utils import get_obj_from_context
10
+ from nautobot.dcim.models import Rack
11
+
12
+
13
+ class RackBreadcrumbs(AncestorsBreadcrumbs):
14
+ def get_detail_items(self, context: Context):
15
+ rack: Rack = get_obj_from_context(context)
16
+ base_items = [
17
+ ModelBreadcrumbItem(),
18
+ InstanceParentBreadcrumbItem(
19
+ parent_key="location",
20
+ ),
21
+ ]
22
+ detail_item = InstanceBreadcrumbItem(
23
+ label=self.detail_item_label,
24
+ )
25
+ if rack.rack_group:
26
+ ancestors_items = self.get_ancestors_items(rack.rack_group)
27
+ return [*base_items, *ancestors_items, InstanceBreadcrumbItem(instance=rack.rack_group), detail_item]
28
+
29
+ return [*base_items, detail_item]
nautobot/dcim/urls.py CHANGED
@@ -31,6 +31,7 @@ router.register("controllers", views.ControllerUIViewSet)
31
31
  router.register("device-families", views.DeviceFamilyUIViewSet)
32
32
  router.register("device-redundancy-groups", views.DeviceRedundancyGroupUIViewSet)
33
33
  router.register("device-types", views.DeviceTypeUIViewSet)
34
+ router.register("devices", views.DeviceUIViewSet)
34
35
  router.register("interface-redundancy-groups", views.InterfaceRedundancyGroupUIViewSet)
35
36
  router.register("interface-redundancy-groups-associations", views.InterfaceRedundancyGroupAssociationUIViewSet)
36
37
  router.register("locations", views.LocationUIViewSet)
@@ -332,27 +333,6 @@ urlpatterns = [
332
333
  name="devicebaytemplate_delete",
333
334
  ),
334
335
  # Devices
335
- path("devices/", views.DeviceListView.as_view(), name="device_list"),
336
- path("devices/add/", views.DeviceEditView.as_view(), name="device_add"),
337
- path("devices/import/", views.DeviceBulkImportView.as_view(), name="device_import"), # 3.0 TODO: remove, unused
338
- path("devices/edit/", views.DeviceBulkEditView.as_view(), name="device_bulk_edit"),
339
- path(
340
- "devices/delete/",
341
- views.DeviceBulkDeleteView.as_view(),
342
- name="device_bulk_delete",
343
- ),
344
- path("devices/<uuid:pk>/", views.DeviceView.as_view(), name="device"),
345
- path("devices/<uuid:pk>/edit/", views.DeviceEditView.as_view(), name="device_edit"),
346
- path(
347
- "devices/<uuid:pk>/delete/",
348
- views.DeviceDeleteView.as_view(),
349
- name="device_delete",
350
- ),
351
- path(
352
- "devices/<uuid:pk>/console-ports/",
353
- views.DeviceConsolePortsView.as_view(),
354
- name="device_consoleports",
355
- ),
356
336
  path(
357
337
  "devices/<uuid:pk>/console-ports/add/",
358
338
  RedirectView.as_view(
@@ -360,11 +340,6 @@ urlpatterns = [
360
340
  ),
361
341
  name="device_consoleports_add",
362
342
  ),
363
- path(
364
- "devices/<uuid:pk>/console-server-ports/",
365
- views.DeviceConsoleServerPortsView.as_view(),
366
- name="device_consoleserverports",
367
- ),
368
343
  path(
369
344
  "devices/<uuid:pk>/console-server-ports/add/",
370
345
  RedirectView.as_view(
@@ -372,21 +347,11 @@ urlpatterns = [
372
347
  ),
373
348
  name="device_consoleserverports_add",
374
349
  ),
375
- path(
376
- "devices/<uuid:pk>/power-ports/",
377
- views.DevicePowerPortsView.as_view(),
378
- name="device_powerports",
379
- ),
380
350
  path(
381
351
  "devices/<uuid:pk>/power-ports/add/",
382
352
  RedirectView.as_view(url="/dcim/power-ports/add/?device=%(pk)s&return_url=/dcim/devices/%(pk)s/power-ports/"),
383
353
  name="device_powerports_add",
384
354
  ),
385
- path(
386
- "devices/<uuid:pk>/power-outlets/",
387
- views.DevicePowerOutletsView.as_view(),
388
- name="device_poweroutlets",
389
- ),
390
355
  path(
391
356
  "devices/<uuid:pk>/power-outlets/add/",
392
357
  RedirectView.as_view(
@@ -394,51 +359,26 @@ urlpatterns = [
394
359
  ),
395
360
  name="device_poweroutlets_add",
396
361
  ),
397
- path(
398
- "devices/<uuid:pk>/interfaces/",
399
- views.DeviceInterfacesView.as_view(),
400
- name="device_interfaces",
401
- ),
402
362
  path(
403
363
  "devices/<uuid:pk>/interfaces/add/",
404
364
  RedirectView.as_view(url="/dcim/interfaces/add/?device=%(pk)s&return_url=/dcim/devices/%(pk)s/interfaces/"),
405
365
  name="device_interfaces_add",
406
366
  ),
407
- path(
408
- "devices/<uuid:pk>/front-ports/",
409
- views.DeviceFrontPortsView.as_view(),
410
- name="device_frontports",
411
- ),
412
367
  path(
413
368
  "devices/<uuid:pk>/front-ports/add/",
414
369
  RedirectView.as_view(url="/dcim/front-ports/add/?device=%(pk)s&return_url=/dcim/devices/%(pk)s/front-ports/"),
415
370
  name="device_frontports_add",
416
371
  ),
417
- path(
418
- "devices/<uuid:pk>/rear-ports/",
419
- views.DeviceRearPortsView.as_view(),
420
- name="device_rearports",
421
- ),
422
372
  path(
423
373
  "devices/<uuid:pk>/rear-ports/add/",
424
374
  RedirectView.as_view(url="/dcim/rear-ports/add/?device=%(pk)s&return_url=/dcim/devices/%(pk)s/rear-ports/"),
425
375
  name="device_rearports_add",
426
376
  ),
427
- path(
428
- "devices/<uuid:pk>/device-bays/",
429
- views.DeviceDeviceBaysView.as_view(),
430
- name="device_devicebays",
431
- ),
432
377
  path(
433
378
  "devices/<uuid:pk>/device-bays/add/",
434
379
  RedirectView.as_view(url="/dcim/device-bays/add/?device=%(pk)s&return_url=/dcim/devices/%(pk)s/device-bays/"),
435
380
  name="device_devicebays_add",
436
381
  ),
437
- path(
438
- "devices/<uuid:pk>/module-bays/",
439
- views.DeviceModuleBaysView.as_view(),
440
- name="device_modulebays",
441
- ),
442
382
  path(
443
383
  "devices/<uuid:pk>/module-bays/add/",
444
384
  RedirectView.as_view(
@@ -446,49 +386,6 @@ urlpatterns = [
446
386
  ),
447
387
  name="device_modulebays_add",
448
388
  ),
449
- path(
450
- "devices/<uuid:pk>/inventory/",
451
- views.DeviceInventoryView.as_view(),
452
- name="device_inventory",
453
- ),
454
- path(
455
- "devices/<uuid:pk>/config-context/",
456
- views.DeviceConfigContextView.as_view(),
457
- name="device_configcontext",
458
- ),
459
- path(
460
- "devices/<uuid:pk>/changelog/",
461
- views.DeviceChangeLogView.as_view(),
462
- name="device_changelog",
463
- kwargs={"model": Device},
464
- ),
465
- path(
466
- "devices/<uuid:pk>/notes/",
467
- ObjectNotesView.as_view(),
468
- name="device_notes",
469
- kwargs={"model": Device},
470
- ),
471
- path(
472
- "devices/<uuid:pk>/dynamic-groups/",
473
- views.DeviceDynamicGroupsView.as_view(),
474
- name="device_dynamicgroups",
475
- kwargs={"model": Device},
476
- ),
477
- path(
478
- "devices/<uuid:pk>/status/",
479
- views.DeviceStatusView.as_view(),
480
- name="device_status",
481
- ),
482
- path(
483
- "devices/<uuid:pk>/lldp-neighbors/",
484
- views.DeviceLLDPNeighborsView.as_view(),
485
- name="device_lldp_neighbors",
486
- ),
487
- path(
488
- "devices/<uuid:pk>/config/",
489
- views.DeviceConfigView.as_view(),
490
- name="device_config",
491
- ),
492
389
  path(
493
390
  "devices/<uuid:device>/services/assign/",
494
391
  ServiceEditView.as_view(),
@@ -500,11 +397,6 @@ urlpatterns = [
500
397
  name="device_add_image",
501
398
  kwargs={"model": Device},
502
399
  ),
503
- path(
504
- "devices/<uuid:pk>/wireless/",
505
- views.DeviceWirelessView.as_view(),
506
- name="device_wireless",
507
- ),
508
400
  # Console ports
509
401
  path("console-ports/", views.ConsolePortListView.as_view(), name="consoleport_list"),
510
402
  path(
nautobot/dcim/utils.py CHANGED
@@ -3,9 +3,11 @@ import uuid
3
3
 
4
4
  from django.contrib.contenttypes.models import ContentType
5
5
  from django.core.exceptions import ValidationError
6
+ from django.utils.html import format_html, format_html_join
6
7
  from netutils.lib_mapper import NAME_TO_ALL_LIB_MAPPER, NAME_TO_LIB_MAPPER_REVERSE
7
8
 
8
9
  from nautobot.core.choices import ColorChoices
10
+ from nautobot.core.templatetags.helpers import hyperlinked_object
9
11
  from nautobot.core.utils.config import get_settings_or_config
10
12
  from nautobot.dcim.choices import InterfaceModeChoices
11
13
 
@@ -141,3 +143,31 @@ def convert_watts_to_va(watts, power_factor):
141
143
  if not watts:
142
144
  return 0
143
145
  return int(watts / power_factor)
146
+
147
+
148
+ def render_software_version_and_image_files(instance, software_version, context):
149
+ display = hyperlinked_object(software_version)
150
+ overridden_software_image_files = instance.software_image_files.all()
151
+ if software_version is not None:
152
+ display += format_html(
153
+ '<ul class="software-image-hierarchy">{}</ul>',
154
+ format_html_join(
155
+ "\n",
156
+ "<li>{}{}</li>",
157
+ [
158
+ [
159
+ hyperlinked_object(img, "image_file_name"),
160
+ " (overridden)" if overridden_software_image_files.exists() else "",
161
+ ]
162
+ for img in software_version.software_image_files.restrict(context["request"].user, "view")
163
+ ],
164
+ ),
165
+ )
166
+ if overridden_software_image_files.exists():
167
+ display += format_html(
168
+ "<br><strong>Software Image Files Overridden:</strong>\n<ul>{}</ul>",
169
+ format_html_join(
170
+ "\n", "<li>{}</li>", [[hyperlinked_object(img)] for img in overridden_software_image_files.all()]
171
+ ),
172
+ )
173
+ return display