nautobot 2.4.11__py3-none-any.whl → 2.4.13__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 (364) hide show
  1. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +1 -114
  2. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +1 -1
  3. nautobot/circuits/views.py +76 -6
  4. nautobot/cloud/navigation.py +1 -1
  5. nautobot/core/jobs/cleanup.py +4 -4
  6. nautobot/core/templates/components/panel/header_extra_content_table.html +12 -1
  7. nautobot/core/templates/components/panel/panel.html +4 -0
  8. nautobot/core/templates/generic/object_retrieve.html +1 -0
  9. nautobot/core/templates/inc/footer.html +4 -4
  10. nautobot/core/tests/test_utils.py +1 -177
  11. nautobot/core/tests/test_views.py +2 -2
  12. nautobot/core/ui/object_detail.py +1 -1
  13. nautobot/core/utils/module_loading.py +58 -63
  14. nautobot/dcim/filters/__init__.py +6 -0
  15. nautobot/dcim/filters/mixins.py +2 -1
  16. nautobot/dcim/migrations/0071_alter_consoleport_options_and_more.py +42 -0
  17. nautobot/dcim/models/device_components.py +10 -2
  18. nautobot/dcim/models/devices.py +28 -0
  19. nautobot/dcim/tables/devices.py +2 -0
  20. nautobot/dcim/templates/dcim/controller/base.html +1 -9
  21. nautobot/dcim/templates/dcim/controller_retrieve.html +2 -83
  22. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +2 -25
  23. nautobot/dcim/templates/dcim/device.html +1 -34
  24. nautobot/dcim/templates/dcim/rack_elevation_list.html +4 -1
  25. nautobot/dcim/templates/dcim/virtualchassis.html +2 -51
  26. nautobot/dcim/templates/dcim/virtualchassis_add.html +2 -22
  27. nautobot/dcim/templates/dcim/virtualchassis_create.html +22 -0
  28. nautobot/dcim/templates/dcim/virtualchassis_edit.html +2 -93
  29. nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +51 -0
  30. nautobot/dcim/templates/dcim/virtualchassis_update.html +93 -0
  31. nautobot/dcim/tests/test_models.py +1 -0
  32. nautobot/dcim/urls.py +2 -59
  33. nautobot/dcim/views.py +180 -191
  34. nautobot/extras/datasources/git.py +2 -2
  35. nautobot/extras/jobs_ui.py +208 -0
  36. nautobot/extras/models/tags.py +4 -0
  37. nautobot/extras/tables.py +1 -1
  38. nautobot/extras/templates/extras/configcontextschema_retrieve.html +2 -2
  39. nautobot/extras/templates/extras/inc/configcontext_data.html +1 -1
  40. nautobot/extras/templates/extras/inc/configcontext_format.html +6 -0
  41. nautobot/extras/templates/extras/inc/json_data.html +1 -1
  42. nautobot/extras/templates/extras/inc/json_format.html +2 -2
  43. nautobot/extras/templates/extras/job_detail.html +1 -326
  44. nautobot/extras/templates/extras/tag_retrieve.html +1 -51
  45. nautobot/extras/views.py +83 -29
  46. nautobot/ipam/migrations/0052_alter_ipaddress_index_together_and_more.py +28 -0
  47. nautobot/ipam/models.py +13 -1
  48. nautobot/ipam/tests/test_api.py +1 -3
  49. nautobot/ipam/utils/testing.py +76 -29
  50. nautobot/project-static/docs/404.html +2 -2
  51. nautobot/project-static/docs/apps/index.html +2 -2
  52. nautobot/project-static/docs/apps/nautobot-apps.html +2 -2
  53. nautobot/project-static/docs/assets/javascripts/{bundle.13a4f30d.min.js → bundle.56ea9cef.min.js} +2 -2
  54. nautobot/project-static/docs/assets/javascripts/{bundle.13a4f30d.min.js.map → bundle.56ea9cef.min.js.map} +2 -2
  55. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +2 -2
  56. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +2 -2
  57. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2 -2
  58. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +2 -2
  59. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +2 -2
  60. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +2 -2
  61. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +2 -2
  62. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +2 -2
  63. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +2 -2
  64. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +2 -2
  65. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +2 -2
  66. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2 -2
  67. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2 -2
  68. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +2 -2
  69. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2 -2
  70. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2 -2
  71. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +2 -2
  72. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +2 -2
  73. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +2 -2
  74. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +2 -2
  75. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2 -2
  76. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +2 -2
  77. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2 -2
  78. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +4 -2
  79. nautobot/project-static/docs/development/apps/api/configuration-view.html +2 -2
  80. nautobot/project-static/docs/development/apps/api/database-backend-config.html +2 -2
  81. nautobot/project-static/docs/development/apps/api/models/django-admin.html +2 -2
  82. nautobot/project-static/docs/development/apps/api/models/global-search.html +2 -2
  83. nautobot/project-static/docs/development/apps/api/models/graphql.html +2 -2
  84. nautobot/project-static/docs/development/apps/api/models/index.html +2 -2
  85. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +2 -2
  86. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +2 -2
  87. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +2 -2
  88. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +2 -2
  89. nautobot/project-static/docs/development/apps/api/platform-features/index.html +2 -2
  90. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +2 -2
  91. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +2 -2
  92. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +2 -2
  93. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +2 -2
  94. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +2 -2
  95. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +2 -2
  96. nautobot/project-static/docs/development/apps/api/prometheus.html +2 -2
  97. nautobot/project-static/docs/development/apps/api/setup.html +2 -2
  98. nautobot/project-static/docs/development/apps/api/testing.html +2 -2
  99. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +2 -2
  100. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +2 -2
  101. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +2 -2
  102. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +2 -2
  103. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +2 -2
  104. nautobot/project-static/docs/development/apps/api/views/base-template.html +2 -2
  105. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +2 -2
  106. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +2 -2
  107. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +2 -2
  108. nautobot/project-static/docs/development/apps/api/views/index.html +2 -2
  109. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +2 -2
  110. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +2 -2
  111. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +2 -2
  112. nautobot/project-static/docs/development/apps/api/views/notes.html +2 -2
  113. nautobot/project-static/docs/development/apps/api/views/rest-api.html +2 -2
  114. nautobot/project-static/docs/development/apps/api/views/urls.html +2 -2
  115. nautobot/project-static/docs/development/apps/index.html +2 -2
  116. nautobot/project-static/docs/development/apps/migration/code-updates.html +2 -2
  117. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +2 -2
  118. nautobot/project-static/docs/development/apps/migration/from-v1.html +2 -2
  119. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +2 -2
  120. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +2 -2
  121. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +2 -2
  122. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +2 -2
  123. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +2 -2
  124. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +2 -2
  125. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +2 -2
  126. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +2 -2
  127. nautobot/project-static/docs/development/apps/porting-from-netbox.html +2 -2
  128. nautobot/project-static/docs/development/core/application-registry.html +2 -2
  129. nautobot/project-static/docs/development/core/best-practices.html +2 -2
  130. nautobot/project-static/docs/development/core/bootstrap-ui.html +2 -2
  131. nautobot/project-static/docs/development/core/caching.html +2 -2
  132. nautobot/project-static/docs/development/core/controllers.html +2 -2
  133. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +2 -2
  134. nautobot/project-static/docs/development/core/generic-views.html +2 -2
  135. nautobot/project-static/docs/development/core/getting-started.html +2 -2
  136. nautobot/project-static/docs/development/core/homepage.html +2 -2
  137. nautobot/project-static/docs/development/core/index.html +2 -2
  138. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +2 -2
  139. nautobot/project-static/docs/development/core/model-checklist.html +2 -2
  140. nautobot/project-static/docs/development/core/model-features.html +2 -2
  141. nautobot/project-static/docs/development/core/natural-keys.html +2 -2
  142. nautobot/project-static/docs/development/core/navigation-menu.html +2 -2
  143. nautobot/project-static/docs/development/core/release-checklist.html +2 -2
  144. nautobot/project-static/docs/development/core/role-internals.html +2 -2
  145. nautobot/project-static/docs/development/core/settings.html +2 -2
  146. nautobot/project-static/docs/development/core/style-guide.html +2 -2
  147. nautobot/project-static/docs/development/core/templates.html +2 -2
  148. nautobot/project-static/docs/development/core/testing.html +2 -2
  149. nautobot/project-static/docs/development/core/ui-component-framework.html +2 -2
  150. nautobot/project-static/docs/development/core/user-preferences.html +2 -2
  151. nautobot/project-static/docs/development/index.html +2 -2
  152. nautobot/project-static/docs/development/jobs/getting-started.html +2 -6
  153. nautobot/project-static/docs/development/jobs/index.html +2 -2
  154. nautobot/project-static/docs/development/jobs/installation.html +2 -2
  155. nautobot/project-static/docs/development/jobs/job-extensions.html +2 -2
  156. nautobot/project-static/docs/development/jobs/job-logging.html +2 -2
  157. nautobot/project-static/docs/development/jobs/job-patterns.html +2 -2
  158. nautobot/project-static/docs/development/jobs/job-structure.html +2 -2
  159. nautobot/project-static/docs/development/jobs/migration/from-v1.html +2 -2
  160. nautobot/project-static/docs/development/jobs/testing.html +2 -2
  161. nautobot/project-static/docs/index.html +2 -2
  162. nautobot/project-static/docs/objects.inv +0 -0
  163. nautobot/project-static/docs/overview/application_stack.html +2 -2
  164. nautobot/project-static/docs/overview/design_philosophy.html +2 -2
  165. nautobot/project-static/docs/release-notes/index.html +2 -2
  166. nautobot/project-static/docs/release-notes/version-1.0.html +2 -2
  167. nautobot/project-static/docs/release-notes/version-1.1.html +2 -2
  168. nautobot/project-static/docs/release-notes/version-1.2.html +2 -2
  169. nautobot/project-static/docs/release-notes/version-1.3.html +2 -2
  170. nautobot/project-static/docs/release-notes/version-1.4.html +2 -2
  171. nautobot/project-static/docs/release-notes/version-1.5.html +2 -2
  172. nautobot/project-static/docs/release-notes/version-1.6.html +2 -2
  173. nautobot/project-static/docs/release-notes/version-2.0.html +2 -2
  174. nautobot/project-static/docs/release-notes/version-2.1.html +2 -2
  175. nautobot/project-static/docs/release-notes/version-2.2.html +2 -2
  176. nautobot/project-static/docs/release-notes/version-2.3.html +2 -2
  177. nautobot/project-static/docs/release-notes/version-2.4.html +211 -2
  178. nautobot/project-static/docs/requirements.txt +1 -1
  179. nautobot/project-static/docs/search/search_index.json +1 -1
  180. nautobot/project-static/docs/sitemap.xml +299 -299
  181. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  182. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +2 -2
  183. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +2 -2
  184. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +2 -2
  185. nautobot/project-static/docs/user-guide/administration/configuration/index.html +2 -2
  186. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +2 -2
  187. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +2 -2
  188. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +2 -2
  189. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +2 -2
  190. nautobot/project-static/docs/user-guide/administration/guides/docker.html +2 -2
  191. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +2 -2
  192. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +2 -2
  193. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +2 -2
  194. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +2 -2
  195. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +2 -2
  196. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +2 -2
  197. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +2 -2
  198. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +2 -2
  199. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +2 -2
  200. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +2 -2
  201. nautobot/project-static/docs/user-guide/administration/installation/index.html +2 -2
  202. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +2 -2
  203. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +2 -2
  204. nautobot/project-static/docs/user-guide/administration/installation/services.html +2 -2
  205. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +2 -2
  206. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +2 -2
  207. nautobot/project-static/docs/user-guide/administration/security/index.html +2 -2
  208. nautobot/project-static/docs/user-guide/administration/security/notices.html +2 -2
  209. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +2 -2
  210. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +2 -2
  211. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +2 -2
  212. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +2 -2
  213. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +2 -2
  214. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +2 -2
  215. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +2 -2
  216. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +2 -2
  217. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +2 -2
  218. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +2 -2
  219. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -2
  220. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +2 -2
  221. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +2 -2
  222. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +2 -2
  223. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +2 -2
  224. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +2 -2
  225. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +2 -2
  226. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +2 -2
  227. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +2 -2
  228. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +2 -2
  229. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +2 -2
  230. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +2 -2
  231. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +2 -2
  232. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +2 -2
  233. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +2 -2
  234. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +2 -2
  235. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +2 -2
  236. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +2 -2
  237. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +2 -2
  238. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +2 -2
  239. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +2 -2
  240. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +2 -2
  241. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +2 -2
  242. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +2 -2
  243. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +2 -2
  244. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +2 -2
  245. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +2 -2
  246. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +2 -2
  247. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +2 -2
  248. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +2 -2
  249. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +2 -2
  250. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +2 -2
  251. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +2 -2
  252. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +2 -2
  253. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +2 -2
  254. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +2 -2
  255. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +2 -2
  256. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +2 -2
  257. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +2 -2
  258. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +2 -2
  259. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +2 -2
  260. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +2 -2
  261. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +2 -2
  262. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +2 -2
  263. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +2 -2
  264. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +2 -2
  265. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +2 -2
  266. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +2 -2
  267. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +2 -2
  268. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +2 -2
  269. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +2 -2
  270. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +2 -2
  271. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +2 -2
  272. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +2 -2
  273. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +2 -2
  274. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +2 -2
  275. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +2 -2
  276. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +2 -2
  277. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +2 -2
  278. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +2 -2
  279. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +2 -2
  280. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +2 -2
  281. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +2 -2
  282. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +2 -2
  283. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +2 -2
  284. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +2 -2
  285. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +2 -2
  286. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +2 -2
  287. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +2 -2
  288. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +2 -2
  289. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +2 -2
  290. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +2 -2
  291. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +2 -2
  292. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +2 -2
  293. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +2 -2
  294. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +2 -2
  295. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +2 -2
  296. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +2 -2
  297. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +2 -2
  298. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +2 -2
  299. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +2 -2
  300. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +2 -2
  301. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +2 -2
  302. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +2 -2
  303. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +2 -2
  304. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +2 -2
  305. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +2 -2
  306. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +2 -2
  307. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +2 -2
  308. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +2 -2
  309. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +2 -2
  310. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +2 -2
  311. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +3 -3
  312. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +2 -2
  313. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +2 -2
  314. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +2 -2
  315. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +2 -2
  316. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +2 -2
  317. nautobot/project-static/docs/user-guide/index.html +2 -2
  318. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +2 -2
  319. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +2 -2
  320. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +2 -2
  321. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +2 -2
  322. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +2 -2
  323. nautobot/project-static/docs/user-guide/platform-functionality/events.html +2 -2
  324. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +2 -2
  325. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +2 -2
  326. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +2 -2
  327. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +2 -2
  328. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +2 -2
  329. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +2 -2
  330. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +2 -2
  331. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +2 -2
  332. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +2 -2
  333. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +2 -2
  334. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +2 -2
  335. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +2 -2
  336. nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +2 -2
  337. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +2 -2
  338. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +2 -2
  339. nautobot/project-static/docs/user-guide/platform-functionality/note.html +2 -2
  340. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +2 -2
  341. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +2 -2
  342. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +2 -2
  343. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +2 -2
  344. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +2 -2
  345. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +2 -2
  346. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +2 -2
  347. nautobot/project-static/docs/user-guide/platform-functionality/role.html +2 -2
  348. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +2 -2
  349. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +2 -2
  350. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +2 -2
  351. nautobot/project-static/docs/user-guide/platform-functionality/status.html +2 -2
  352. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +2 -2
  353. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +2 -2
  354. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +2 -2
  355. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +2 -2
  356. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +2 -2
  357. nautobot/wireless/navigation.py +1 -1
  358. nautobot/wireless/tables.py +13 -5
  359. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/METADATA +1 -1
  360. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/RECORD +364 -357
  361. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/LICENSE.txt +0 -0
  362. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/NOTICE +0 -0
  363. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/WHEEL +0 -0
  364. {nautobot-2.4.11.dist-info → nautobot-2.4.13.dist-info}/entry_points.txt +0 -0
@@ -1,13 +1,30 @@
1
- from importlib.machinery import FileFinder, SOURCE_SUFFIXES, SourceFileLoader
2
- from importlib.util import module_from_spec
1
+ from contextlib import contextmanager
2
+ import importlib
3
+ from importlib.util import find_spec, module_from_spec
3
4
  from keyword import iskeyword
4
5
  import logging
6
+ import os
5
7
  import pkgutil
6
8
  import sys
7
9
 
8
10
  logger = logging.getLogger(__name__)
9
11
 
10
12
 
13
+ @contextmanager
14
+ def _temporarily_add_to_sys_path(path):
15
+ """
16
+ Allow loading of modules and packages from within the provided directory by temporarily modifying `sys.path`.
17
+
18
+ On exit, it restores the original `sys.path` value.
19
+ """
20
+ old_sys_path = sys.path.copy()
21
+ sys.path.insert(0, path)
22
+ try:
23
+ yield
24
+ finally:
25
+ sys.path = old_sys_path
26
+
27
+
11
28
  def clear_module_from_sys_modules(module_name):
12
29
  """
13
30
  Remove the module and all its submodules from sys.modules.
@@ -39,7 +56,7 @@ def check_name_safe_to_import_privately(name: str) -> tuple[bool, str]:
39
56
  return True, "a valid and non-conflicting module name"
40
57
 
41
58
 
42
- def import_modules_privately(path, module_path=None, module_prefix="", ignore_import_errors=True):
59
+ def import_modules_privately(path, module_path=None, ignore_import_errors=True):
43
60
  """
44
61
  Import modules from the filesystem without adding the path permanently to `sys.path`.
45
62
 
@@ -55,71 +72,49 @@ def import_modules_privately(path, module_path=None, module_prefix="", ignore_im
55
72
  ignore_import_errors (bool): Exceptions raised while importing modules will be caught and logged.
56
73
  If this is set as False, they will then be re-raised to be handled by the caller of this function.
57
74
  """
58
- loaded_modules = []
59
- # We formerly used pkgutil.walk_packages() here to handle submodule loading with a multi-entry module_path,
60
- # but that has the downside (and risk!) of automatically importing all packages that it finds in the given path,
61
- # whether or not we actually want to do so. So instead, for the case where a module_path is provided, we need to
62
- # iteratively import each submodule ourselves.
63
- if module_path:
64
- # Git repository case - e.g. import_modules_privately(settings.GIT_ROOT, module_path=[repository_slug, "jobs"])
65
- # Here we want to ONLY auto-load the module sequence identified by module_path.
66
- permitted, reason = check_name_safe_to_import_privately(module_path[0])
67
- if not permitted:
68
- logger.error("Unable to load module %r from %s as it is %s", module_path[0], path, reason)
69
- else:
70
- module = None
71
- module_name = module_path.pop(0)
72
- submodule_name = module_name
73
- try:
74
- while True:
75
- finder = FileFinder(path, (SourceFileLoader, SOURCE_SUFFIXES))
76
- finder.invalidate_caches()
77
- spec = finder.find_spec(module_name)
78
- if spec is None or spec.loader is None:
79
- logger.error("Unable to find module spec and/or loader for %r", submodule_name)
80
- break
81
- spec.name = submodule_name
82
- spec.loader.name = submodule_name
83
- submodule = module_from_spec(spec)
84
- sys.modules[submodule_name] = submodule
85
- spec.loader.exec_module(submodule)
86
- if module is not None:
87
- setattr(module, module_name, submodule)
88
- module = submodule
89
- loaded_modules.append(module)
90
- if module_path:
91
- submodule_name = f"{module_name}.{module_path[0]}"
92
- module_name = module_path.pop(0)
93
- path = module.__path__[0]
94
- else:
95
- break
96
- except Exception as exc:
97
- logger.error("Unable to load module %s from %s: %s", module_name, path, exc)
98
- if not ignore_import_errors:
99
- raise
75
+ if module_path is None:
76
+ module_path = []
77
+ module_prefix = None
100
78
  else:
101
- # JOBS_ROOT case - import ALL top-level modules/packages that we can find in the given path;
102
- # they can implement and import submodules as desired by themselves, but we only autoimport top-level ones.
103
- for finder, discovered_module_name, _ in pkgutil.iter_modules([path]):
104
- permitted, reason = check_name_safe_to_import_privately(discovered_module_name)
105
- if not permitted:
106
- logger.error("Unable to load module %r from %s as it is %s", discovered_module_name, path, reason)
79
+ module_prefix = ".".join(module_path)
80
+ with _temporarily_add_to_sys_path(path):
81
+ for finder, discovered_module_name, is_package in pkgutil.walk_packages([path], onerror=logger.error):
82
+ if module_prefix and not (
83
+ module_prefix.startswith(f"{discovered_module_name}.") # my_repo/__init__.py
84
+ or discovered_module_name == module_prefix # my_repo/jobs.py
85
+ or discovered_module_name.startswith(f"{module_prefix}.") # my_repo/jobs/foobar.py
86
+ ):
107
87
  continue
108
- module_name = discovered_module_name
109
- if module_name in sys.modules:
110
- clear_module_from_sys_modules(module_name)
111
-
112
88
  try:
113
- spec = finder.find_spec(discovered_module_name)
114
- if spec is None or spec.loader is None:
115
- logger.error("Unable to find module spec and/or loader for %r", discovered_module_name)
89
+ existing_module = find_spec(discovered_module_name)
90
+ except (ModuleNotFoundError, ValueError):
91
+ existing_module = None
92
+ if existing_module is not None:
93
+ existing_module_path = os.path.realpath(existing_module.origin)
94
+ if not existing_module_path.startswith(path):
95
+ logger.error(
96
+ "Unable to load module %s from %s as it conflicts with existing module %s",
97
+ discovered_module_name,
98
+ path,
99
+ existing_module_path,
100
+ )
116
101
  continue
117
- module = module_from_spec(spec)
118
- sys.modules[module_name] = module
119
- spec.loader.exec_module(module)
120
- loaded_modules.append(module)
102
+
103
+ if discovered_module_name in sys.modules:
104
+ clear_module_from_sys_modules(discovered_module_name)
105
+
106
+ try:
107
+ if not is_package:
108
+ spec = finder.find_spec(discovered_module_name)
109
+ if spec is None:
110
+ raise ValueError("Unable to find module spec")
111
+ module = module_from_spec(spec)
112
+ sys.modules[discovered_module_name] = module
113
+ spec.loader.exec_module(module)
114
+ else:
115
+ module = importlib.import_module(discovered_module_name)
116
+ importlib.reload(module)
121
117
  except Exception as exc:
122
118
  logger.error("Unable to load module %s from %s: %s", discovered_module_name, path, exc)
123
119
  if not ignore_import_errors:
124
120
  raise
125
- return loaded_modules
@@ -961,6 +961,12 @@ class DeviceFilterSet(
961
961
  field_name="controller_managed_device_group__wireless_networks",
962
962
  label="Has wireless networks",
963
963
  )
964
+ controller = NaturalKeyOrPKMultipleChoiceFilter(
965
+ field_name="controller_managed_device_group__controller",
966
+ queryset=Controller.objects.all(),
967
+ to_field_name="name",
968
+ label="Controller (name or ID)",
969
+ )
964
970
 
965
971
  def filter_ip_addresses(self, queryset, name, value):
966
972
  pk_values = set(item for item in value if is_uuid(item))
@@ -39,6 +39,7 @@ from nautobot.dcim.models import (
39
39
  RearPortTemplate,
40
40
  )
41
41
  from nautobot.extras.filters import CustomFieldModelFilterSetMixin
42
+ from nautobot.extras.filters.mixins import RelationshipModelFilterSetMixin
42
43
 
43
44
 
44
45
  class CableTerminationModelFilterSetMixin(django_filters.FilterSet):
@@ -101,7 +102,7 @@ class DeviceComponentModelFilterSetMixin(CustomFieldModelFilterSetMixin):
101
102
  )
102
103
 
103
104
 
104
- class ModularDeviceComponentModelFilterSetMixin(DeviceComponentModelFilterSetMixin):
105
+ class ModularDeviceComponentModelFilterSetMixin(DeviceComponentModelFilterSetMixin, RelationshipModelFilterSetMixin):
105
106
  module = NaturalKeyOrPKMultipleChoiceFilter(
106
107
  queryset=Module.objects.all(),
107
108
  to_field_name="module_type__model",
@@ -0,0 +1,42 @@
1
+ # Generated by Django 4.2.20 on 2025-07-17 20:24
2
+
3
+ from django.db import migrations
4
+
5
+ import nautobot.core.models.query_functions
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ dependencies = [
10
+ ("dcim", "0070_modulefamily_models"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterModelOptions(
15
+ name="consoleport",
16
+ options={"ordering": ("device", "module__id", "_name")},
17
+ ),
18
+ migrations.AlterModelOptions(
19
+ name="consoleserverport",
20
+ options={"ordering": ("device", "module__id", "_name")},
21
+ ),
22
+ migrations.AlterModelOptions(
23
+ name="frontport",
24
+ options={"ordering": ("device", "module__id", "_name")},
25
+ ),
26
+ migrations.AlterModelOptions(
27
+ name="interface",
28
+ options={"ordering": ("device", "module__id", nautobot.core.models.query_functions.CollateAsChar("_name"))},
29
+ ),
30
+ migrations.AlterModelOptions(
31
+ name="poweroutlet",
32
+ options={"ordering": ("device", "module__id", "_name")},
33
+ ),
34
+ migrations.AlterModelOptions(
35
+ name="powerport",
36
+ options={"ordering": ("device", "module__id", "_name")},
37
+ ),
38
+ migrations.AlterModelOptions(
39
+ name="rearport",
40
+ options={"ordering": ("device", "module__id", "_name")},
41
+ ),
42
+ ]
@@ -2,6 +2,7 @@ import re
2
2
 
3
3
  from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
4
4
  from django.contrib.contenttypes.models import ContentType
5
+ from django.core.cache import cache
5
6
  from django.core.exceptions import ObjectDoesNotExist, ValidationError
6
7
  from django.core.validators import MaxValueValidator, MinValueValidator
7
8
  from django.db import models, transaction
@@ -123,7 +124,7 @@ class ModularComponentModel(ComponentModel):
123
124
 
124
125
  class Meta:
125
126
  abstract = True
126
- ordering = ("device", "module", "_name")
127
+ ordering = ("device", "module__id", "_name") # Module.ordering is complex/expensive so don't order by module
127
128
  constraints = [
128
129
  models.UniqueConstraint(
129
130
  fields=("device", "name"),
@@ -646,7 +647,7 @@ class Interface(ModularComponentModel, CableTermination, PathEndpoint, BaseInter
646
647
  )
647
648
 
648
649
  class Meta(ModularComponentModel.Meta):
649
- ordering = ("device", "module", CollateAsChar("_name"))
650
+ ordering = ("device", "module__id", CollateAsChar("_name")) # Module.ordering is complex; don't order by module
650
651
 
651
652
  def clean(self):
652
653
  super().clean()
@@ -1311,3 +1312,10 @@ class ModuleBay(PrimaryModel):
1311
1312
  self.position = self.name
1312
1313
 
1313
1314
  clean.alters_data = True
1315
+
1316
+ def save(self, *args, **kwargs):
1317
+ super().save(*args, **kwargs)
1318
+
1319
+ if self.parent_device is not None:
1320
+ # Set the has_module_bays cache key on the parent device - see Device.has_module_bays()
1321
+ cache.set(f"nautobot.dcim.device.{self.parent_device.pk}.has_module_bays", True, timeout=5)
@@ -2,6 +2,7 @@ from collections import OrderedDict
2
2
 
3
3
  from django.contrib.contenttypes.fields import GenericRelation
4
4
  from django.contrib.contenttypes.models import ContentType
5
+ from django.core.cache import cache
5
6
  from django.core.exceptions import ValidationError
6
7
  from django.core.serializers.json import DjangoJSONEncoder
7
8
  from django.core.validators import MaxValueValidator, MinValueValidator
@@ -30,6 +31,7 @@ from nautobot.dcim.utils import get_all_network_driver_mappings, get_network_dri
30
31
  from nautobot.extras.models import ChangeLoggedModel, ConfigContextModel, RoleField, StatusField
31
32
  from nautobot.extras.querysets import ConfigContextModelQuerySet
32
33
  from nautobot.extras.utils import extras_features
34
+ from nautobot.wireless.models import ControllerManagedDeviceGroupWirelessNetworkAssignment
33
35
 
34
36
  from .device_components import (
35
37
  ConsolePort,
@@ -895,6 +897,8 @@ class Device(PrimaryModel, ConfigContextModel):
895
897
  instantiated_components = []
896
898
  for model, templates in component_models:
897
899
  model.objects.bulk_create([x.instantiate(device=self) for x in templates])
900
+ cache_key = f"nautobot.dcim.device.{self.pk}.has_module_bays"
901
+ cache.delete(cache_key)
898
902
  return instantiated_components
899
903
 
900
904
  create_components.alters_data = True
@@ -987,6 +991,18 @@ class Device(PrimaryModel, ConfigContextModel):
987
991
  """
988
992
  return Device.objects.filter(parent_bay__device=self.pk)
989
993
 
994
+ @property
995
+ def has_module_bays(self) -> bool:
996
+ """
997
+ Cacheable property for determining whether this Device has any ModuleBays, and therefore may contain Modules.
998
+ """
999
+ cache_key = f"nautobot.dcim.device.{self.pk}.has_module_bays"
1000
+ module_bays_exists = cache.get(cache_key)
1001
+ if module_bays_exists is None:
1002
+ module_bays_exists = self.module_bays.exists()
1003
+ cache.set(cache_key, module_bays_exists, timeout=5)
1004
+ return module_bays_exists
1005
+
990
1006
  @property
991
1007
  def all_modules(self):
992
1008
  """
@@ -997,6 +1013,9 @@ class Device(PrimaryModel, ConfigContextModel):
997
1013
  # We artificially limit the recursion to 4 levels or we would be stuck in an infinite loop.
998
1014
  recursion_depth = MODULE_RECURSION_DEPTH_LIMIT
999
1015
  qs = Module.objects.all()
1016
+ if not self.has_module_bays:
1017
+ # Short-circuit to avoid an expensive nested query
1018
+ return qs.none()
1000
1019
  query = Q()
1001
1020
  for level in range(recursion_depth):
1002
1021
  recursive_query = "parent_module_bay__parent_module__" * level
@@ -1456,6 +1475,15 @@ class Controller(PrimaryModel):
1456
1475
  return format_html('<span class="text-muted">&mdash;</span>')
1457
1476
  return format_html_join(" ", '<span class="label label-default">{}</span>', ((v,) for v in self.capabilities))
1458
1477
 
1478
+ @property
1479
+ def wireless_network_assignments(self):
1480
+ """
1481
+ Returns all Controller Managed Device Group Wireless Network Assignment linked to this controller.
1482
+ """
1483
+ return ControllerManagedDeviceGroupWirelessNetworkAssignment.objects.filter(
1484
+ controller_managed_device_group__controller=self
1485
+ )
1486
+
1459
1487
 
1460
1488
  @extras_features(
1461
1489
  "custom_links",
@@ -181,6 +181,7 @@ class DeviceTable(StatusTableMixin, RoleTableMixin, BaseTable):
181
181
  software_version = tables.Column(linkify=True, verbose_name="Software Version")
182
182
  secrets_group = tables.Column(linkify=True)
183
183
  capabilities = tables.Column(orderable=False, accessor="controller_managed_device_group.capabilities")
184
+ manufacturer = tables.Column(orderable=False, accessor="device_type.manufacturer")
184
185
  tags = TagColumn(url_name="dcim:device_list")
185
186
  actions = ButtonsColumn(Device)
186
187
 
@@ -213,6 +214,7 @@ class DeviceTable(StatusTableMixin, RoleTableMixin, BaseTable):
213
214
  "controller_managed_device_group",
214
215
  "secrets_group",
215
216
  "capabilities",
217
+ "manufacturer",
216
218
  "tags",
217
219
  "actions",
218
220
  )
@@ -1,10 +1,2 @@
1
1
  {% extends 'generic/object_retrieve.html' %}
2
- {% load helpers %}
3
-
4
- {% block extra_nav_tabs %}
5
- {% if 'wireless' in object.capabilities %}
6
- <li role="presentation" {% if active_tab == 'wireless-networks' %} class="active"{% endif %}>
7
- <a href="{% url 'dcim:controller_wirelessnetworks' pk=object.pk %}">Wireless Networks</a>
8
- </li>
9
- {% endif %}
10
- {% endblock extra_nav_tabs %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -1,83 +1,2 @@
1
- {% extends 'dcim/controller/base.html' %}
2
- {% load helpers %}
3
-
4
- {% block content_left_page %}
5
- <div class="panel panel-default">
6
- <div class="panel-heading">
7
- <strong>Controller</strong>
8
- </div>
9
- <div class="table-responsive">
10
- <table class="table table-hover panel-body attr-table">
11
- <tr>
12
- <td>Name</td>
13
- <td>{{ object.name|placeholder }}</td>
14
- </tr>
15
- <tr>
16
- <td>Status</td>
17
- <td>
18
- {{ object.status|hyperlinked_object_with_color }}
19
- </td>
20
- </tr>
21
- <tr>
22
- <td>Role</td>
23
- <td>{{ object.role|hyperlinked_object_with_color }}</td>
24
- </tr>
25
- <tr>
26
- <td>Capabilities</td>
27
- <td>{{ object.get_capabilities_display }}</td>
28
- </tr>
29
- <tr>
30
- <td>Location</td>
31
- <td>{{ object.location|hyperlinked_object }}</td>
32
- </tr>
33
- <tr>
34
- <td>Platform</td>
35
- <td>{{ object.platform|hyperlinked_object }}</td>
36
- </tr>
37
- {% include 'inc/tenant_table_row.html' %}
38
- <tr>
39
- <td>Description</td>
40
- <td>{{ object.description|placeholder }}</td>
41
- </tr>
42
- </table>
43
- </div>
44
- </div>
45
- {% endblock content_left_page %}
46
-
47
- {% block content_right_page %}
48
- <div class="panel panel-default">
49
- <div class="panel-heading">
50
- <strong>Integration</strong>
51
- </div>
52
- <div class="table-responsive">
53
- <table class="table table-hover panel-body attr-table">
54
- <tr>
55
- <td>External Integration</td>
56
- <td>{{ object.external_integration|hyperlinked_object }}</td>
57
- </tr>
58
- {% if object.controller_device %}
59
- <tr>
60
- <td>Controller Device</td>
61
- <td>{{ object.controller_device|hyperlinked_object }}</td>
62
- </tr>
63
- {% endif %}
64
- {% if object.controller_device_redundancy_group %}
65
- <tr>
66
- <td>Controller Device Redundancy Group</td>
67
- <td>{{ object.controller_device_redundancy_group|hyperlinked_object }}</td>
68
- </tr>
69
- {% endif %}
70
- </table>
71
- </div>
72
- </div>
73
- {% endblock content_right_page %}
74
-
75
- {% block content_full_width_page %}
76
- <div class="panel panel-default">
77
- <div class="panel-heading">
78
- <strong>Managed Devices</strong>
79
- </div>
80
- {% include 'responsive_table.html' with table=devices_table %}
81
- </div>
82
- {% include 'inc/paginator.html' with paginator=devices_table.paginator page=devices_table.page %}
83
- {% endblock content_full_width_page %}
1
+ {% extends 'generic/object_retrieve.html' %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -1,25 +1,2 @@
1
- {% extends 'dcim/controller/base.html' %}
2
- {% load helpers %}
3
-
4
- {% block content %}
5
- <form method="post">
6
- {% csrf_token %}
7
- <div class="panel panel-default">
8
- <div class="panel-heading">
9
- <strong>Wireless Networks</strong>
10
- <div class="pull-right noprint">
11
- {% if request.user.is_authenticated %}
12
- {% table_config_button_small wireless_networks_table %}
13
- {% endif %}
14
- </div>
15
- </div>
16
- {% include 'responsive_table.html' with table=wireless_networks_table %}
17
- </div>
18
- </form>
19
- {% table_config_form wireless_networks_table %}
20
- {% endblock content %}
21
-
22
- {% block javascript %}
23
- {{ block.super }}
24
- <script src="{% versioned_static 'js/tableconfig.js' %}"></script>
25
- {% endblock javascript %}
1
+ {% extends 'generic/object_retrieve.html' %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -398,40 +398,7 @@
398
398
  </div>
399
399
  </div>
400
400
  {% endif %}
401
- {% if object.is_dynamic_group_associable_model and perms.extras.view_dynamicgroup %}
402
- <div id="dynamic_groups" role="tabpanel" class="tab-pane {% if request.GET.tab == 'dynamic_groups' %}active{% else %}fade{% endif %}">
403
- <div class="row">
404
- <div class="col-md-12">
405
- <div class="alert alert-warning">
406
- Dynamic group membership is cached for performance reasons,
407
- therefore this table may not always be up-to-date.
408
- <br>You can refresh the membership of any specific group by navigating to it from the list below
409
- or from the <a href="{% url 'extras:dynamicgroup_list' %}">Dynamic Groups list view</a>.
410
- <br>You can also refresh the membership of all groups by running the
411
- <a href="{% url 'extras:job_run_by_class_path' class_path='nautobot.core.jobs.groups.RefreshDynamicGroupCaches' %}">Refresh Dynamic Group Caches job</a>.
412
- </div>
413
- </div>
414
- </div>
415
- <div class="row">
416
- <div class="col-md-12">
417
- <form method="post">
418
- {% csrf_token %}
419
- <div class="panel panel-default">
420
- <div class="panel-heading">
421
- <strong>Dynamic Groups</strong>
422
- <div class="pull-right noprint">
423
- <!-- Insert table config button here -->
424
- </div>
425
- </div>
426
- <div class="table-responsive">
427
- {% render_table associated_dynamic_groups_table 'inc/table.html' %}
428
- </div>
429
- </div>
430
- </form>
431
- </div>
432
- </div>
433
- </div>
434
- {% endif %}
401
+ {% comment %}The dynamic_groups tab is intentionally omitted here for performance reasons.{% endcomment %}
435
402
  {% if object.is_metadata_associable_model and perms.extras.view_objectmetadata %}
436
403
  <div id="object_metadata" role="tabpanel" class="tab-pane {% if request.GET.tab == 'object_metadata' %}active{% else %}fade{% endif %}">
437
404
  <div class="row">
@@ -3,8 +3,11 @@
3
3
  {% load static %}
4
4
 
5
5
  {% block buttons %}
6
+ <button class="btn btn-default toggle-fullname" selected="selected">
7
+ <span class="mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Device Full Name
8
+ </button>
6
9
  <button class="btn btn-default toggle-images" selected="selected">
7
- <span class="mdi mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
10
+ <span class="mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
8
11
  </button>
9
12
  <div class="btn-group" role="group">
10
13
  <a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='front' %}" class="btn btn-default{% if rack_face == 'front' %} active{% endif %}">Front</a>
@@ -1,51 +1,2 @@
1
- {% extends 'generic/object_retrieve.html' %}
2
- {% load helpers %}
3
-
4
- {% block content_left_page %}
5
- <div class="panel panel-default">
6
- <div class="panel-heading">
7
- <strong>Virtual Chassis</strong>
8
- </div>
9
- <table class="table table-hover panel-body attr-table">
10
- <tr>
11
- <td>Domain</td>
12
- <td>{{ object.domain|placeholder }}</td>
13
- </tr>
14
- <tr>
15
- <td>Master</td>
16
- <td>{{ object.master|hyperlinked_object }}</td>
17
- </tr>
18
- </table>
19
- </div>
20
- {% endblock content_left_page %}
21
-
22
- {% block content_right_page %}
23
- <div class="panel panel-default">
24
- <div class="panel-heading">
25
- <strong>Members</strong>
26
- </div>
27
- <table class="table table-hover panel-body attr-table">
28
- <tr>
29
- <th>Device</th>
30
- <th>Position</th>
31
- <th>Master</th>
32
- <th>Priority</th>
33
- </tr>
34
- {% for vc_member in members %}
35
- <tr{% if vc_member == device %} class="info"{% endif %}>
36
- <td>{{ vc_member|hyperlinked_object }}</td>
37
- <td><span class="badge badge-default">{{ vc_member.vc_position }}</span></td>
38
- <td>{% if object.master == vc_member %}{{ True | render_boolean }}{% endif %}</td>
39
- <td>{{ vc_member.vc_priority|placeholder }}</td>
40
- </tr>
41
- {% endfor %}
42
- </table>
43
- {% if perms.dcim.change_virtualchassis %}
44
- <div class="panel-footer text-right noprint">
45
- <a href="{% url 'dcim:virtualchassis_add_member' pk=object.pk %}?location={{ object.master.location.pk }}&rack={{ object.master.rack.pk }}" class="btn btn-primary btn-xs">
46
- <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Member
47
- </a>
48
- </div>
49
- {% endif %}
50
- </div>
51
- {% endblock content_right_page %}
1
+ {% extends 'dcim/virtualchassis_retrieve.html' %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -1,22 +1,2 @@
1
- {% extends 'generic/object_create.html' %}
2
- {% load form_helpers %}
3
-
4
- {% block form %}
5
- <div class="panel panel-default">
6
- <div class="panel-heading"><strong>Virtual Chassis</strong></div>
7
- <div class="panel-body">
8
- {% render_field form.name %}
9
- {% render_field form.domain %}
10
- </div>
11
- </div>
12
- <div class="panel panel-default">
13
- <div class="panel-heading"><strong>Member Devices</strong></div>
14
- <div class="panel-body">
15
- {% render_field form.location %}
16
- {% render_field form.rack %}
17
- {% render_field form.members %}
18
- {% render_field form.initial_position %}
19
- </div>
20
- </div>
21
- {% include 'inc/extras_features_edit_form_fields.html' %}
22
- {% endblock %}
1
+ {% extends 'dcim/virtualchassis_create.html' %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -0,0 +1,22 @@
1
+ {% extends 'generic/object_create.html' %}
2
+ {% load form_helpers %}
3
+
4
+ {% block form %}
5
+ <div class="panel panel-default">
6
+ <div class="panel-heading"><strong>Virtual Chassis</strong></div>
7
+ <div class="panel-body">
8
+ {% render_field form.name %}
9
+ {% render_field form.domain %}
10
+ </div>
11
+ </div>
12
+ <div class="panel panel-default">
13
+ <div class="panel-heading"><strong>Member Devices</strong></div>
14
+ <div class="panel-body">
15
+ {% render_field form.location %}
16
+ {% render_field form.rack %}
17
+ {% render_field form.members %}
18
+ {% render_field form.initial_position %}
19
+ </div>
20
+ </div>
21
+ {% include 'inc/extras_features_edit_form_fields.html' %}
22
+ {% endblock %}