nautobot 2.4.5__py3-none-any.whl → 2.4.7__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 (410) hide show
  1. nautobot/apps/forms.py +2 -0
  2. nautobot/circuits/templates/circuits/providernetwork.html +1 -1
  3. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +2 -55
  4. nautobot/circuits/views.py +20 -23
  5. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +2 -40
  6. nautobot/cloud/views.py +12 -0
  7. nautobot/core/api/mixins.py +10 -0
  8. nautobot/core/api/urls.py +2 -2
  9. nautobot/core/api/views.py +39 -1
  10. nautobot/core/celery/encoders.py +2 -2
  11. nautobot/core/forms/__init__.py +2 -0
  12. nautobot/core/forms/fields.py +23 -7
  13. nautobot/core/forms/utils.py +1 -0
  14. nautobot/core/forms/widgets.py +18 -0
  15. nautobot/core/jobs/bulk_actions.py +1 -1
  16. nautobot/core/management/commands/generate_test_data.py +1 -1
  17. nautobot/core/models/name_color_content_types.py +9 -0
  18. nautobot/core/models/validators.py +7 -0
  19. nautobot/core/settings.py +0 -14
  20. nautobot/core/settings.yaml +0 -28
  21. nautobot/core/tables.py +6 -1
  22. nautobot/core/templates/generic/object_retrieve.html +1 -1
  23. nautobot/core/templates/widgets/sluginput.html +5 -1
  24. nautobot/core/templatetags/helpers.py +15 -1
  25. nautobot/core/testing/api.py +18 -0
  26. nautobot/core/testing/integration.py +6 -2
  27. nautobot/core/tests/nautobot_config.py +0 -2
  28. nautobot/core/tests/runner.py +17 -140
  29. nautobot/core/tests/test_api.py +4 -4
  30. nautobot/core/tests/test_authentication.py +83 -4
  31. nautobot/core/tests/test_forms.py +11 -8
  32. nautobot/core/tests/test_graphql.py +9 -0
  33. nautobot/core/tests/test_jobs.py +7 -0
  34. nautobot/core/ui/object_detail.py +47 -3
  35. nautobot/core/utils/lookup.py +2 -2
  36. nautobot/dcim/factory.py +2 -0
  37. nautobot/dcim/filters/__init__.py +5 -0
  38. nautobot/dcim/forms.py +27 -1
  39. nautobot/dcim/migrations/0068_alter_softwareimagefile_download_url.py +19 -0
  40. nautobot/dcim/migrations/0069_softwareimagefile_external_integration.py +25 -0
  41. nautobot/dcim/models/devices.py +9 -2
  42. nautobot/dcim/models/locations.py +9 -0
  43. nautobot/dcim/tables/devices.py +1 -0
  44. nautobot/dcim/templates/dcim/device_list.html +1 -1
  45. nautobot/dcim/templates/dcim/devicetype.html +1 -1
  46. nautobot/dcim/templates/dcim/manufacturer.html +1 -63
  47. nautobot/dcim/templates/dcim/module_list.html +1 -1
  48. nautobot/dcim/templates/dcim/moduletype_retrieve.html +1 -1
  49. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +4 -0
  50. nautobot/dcim/tests/integration/test_module_bay_position.py +125 -0
  51. nautobot/dcim/tests/test_api.py +74 -31
  52. nautobot/dcim/tests/test_filters.py +2 -0
  53. nautobot/dcim/tests/test_models.py +78 -0
  54. nautobot/dcim/tests/test_views.py +7 -1
  55. nautobot/dcim/urls.py +1 -45
  56. nautobot/dcim/views.py +35 -66
  57. nautobot/extras/choices.py +4 -0
  58. nautobot/extras/filters/__init__.py +6 -0
  59. nautobot/extras/forms/forms.py +83 -11
  60. nautobot/extras/models/customfields.py +10 -9
  61. nautobot/extras/plugins/marketplace_manifest.yml +18 -0
  62. nautobot/extras/signals.py +43 -4
  63. nautobot/extras/tables.py +4 -5
  64. nautobot/extras/tasks.py +4 -2
  65. nautobot/extras/templates/extras/contact_retrieve.html +1 -58
  66. nautobot/extras/templates/extras/exporttemplate.html +1 -53
  67. nautobot/extras/templates/extras/inc/panel_changelog.html +1 -1
  68. nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
  69. nautobot/extras/templates/extras/status.html +1 -37
  70. nautobot/extras/templates/extras/team_retrieve.html +1 -58
  71. nautobot/extras/tests/integration/test_notes.py +1 -1
  72. nautobot/extras/tests/test_api.py +22 -7
  73. nautobot/extras/tests/test_changelog.py +4 -4
  74. nautobot/extras/tests/test_customfields.py +27 -0
  75. nautobot/extras/tests/test_plugins.py +19 -13
  76. nautobot/extras/tests/test_relationships.py +9 -0
  77. nautobot/extras/tests/test_tags.py +2 -2
  78. nautobot/extras/tests/test_views.py +37 -6
  79. nautobot/extras/urls.py +3 -100
  80. nautobot/extras/views.py +111 -133
  81. nautobot/ipam/tables.py +7 -2
  82. nautobot/ipam/templates/ipam/namespace_retrieve.html +0 -41
  83. nautobot/ipam/templates/ipam/service.html +2 -46
  84. nautobot/ipam/templates/ipam/service_edit.html +1 -17
  85. nautobot/ipam/templates/ipam/service_retrieve.html +7 -0
  86. nautobot/ipam/tests/migration/__init__.py +0 -0
  87. nautobot/ipam/tests/migration/test_migrations.py +510 -0
  88. nautobot/ipam/tests/test_api.py +66 -36
  89. nautobot/ipam/tests/test_filters.py +0 -10
  90. nautobot/ipam/tests/test_views.py +44 -2
  91. nautobot/ipam/urls.py +2 -47
  92. nautobot/ipam/utils/migrations.py +185 -152
  93. nautobot/ipam/utils/testing.py +177 -0
  94. nautobot/ipam/views.py +95 -157
  95. nautobot/project-static/css/base.css +5 -0
  96. nautobot/project-static/docs/404.html +0 -2
  97. nautobot/project-static/docs/apps/index.html +0 -2
  98. nautobot/project-static/docs/apps/nautobot-apps.html +0 -2
  99. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +0 -2
  100. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +0 -2
  101. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +0 -2
  102. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +0 -2
  103. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +0 -2
  104. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +0 -2
  105. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +0 -2
  106. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +0 -2
  107. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +0 -2
  108. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +0 -2
  109. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +0 -2
  110. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +0 -2
  111. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +62 -2
  112. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +0 -2
  113. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +0 -2
  114. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +47 -2
  115. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +0 -2
  116. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +0 -2
  117. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +18 -2
  118. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +0 -2
  119. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +70 -5
  120. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +0 -2
  121. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +0 -2
  122. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +0 -2
  123. nautobot/project-static/docs/development/apps/api/configuration-view.html +0 -2
  124. nautobot/project-static/docs/development/apps/api/database-backend-config.html +0 -2
  125. nautobot/project-static/docs/development/apps/api/models/django-admin.html +0 -2
  126. nautobot/project-static/docs/development/apps/api/models/global-search.html +0 -2
  127. nautobot/project-static/docs/development/apps/api/models/graphql.html +0 -2
  128. nautobot/project-static/docs/development/apps/api/models/index.html +0 -2
  129. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +0 -2
  130. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +0 -2
  131. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +0 -2
  132. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +0 -2
  133. nautobot/project-static/docs/development/apps/api/platform-features/index.html +0 -2
  134. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +0 -2
  135. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +0 -2
  136. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +0 -2
  137. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +0 -2
  138. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +0 -2
  139. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +0 -2
  140. nautobot/project-static/docs/development/apps/api/prometheus.html +0 -2
  141. nautobot/project-static/docs/development/apps/api/setup.html +0 -2
  142. nautobot/project-static/docs/development/apps/api/testing.html +0 -89
  143. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +0 -2
  144. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +0 -2
  145. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +0 -2
  146. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +0 -2
  147. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +0 -2
  148. nautobot/project-static/docs/development/apps/api/views/base-template.html +0 -2
  149. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +0 -2
  150. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +0 -2
  151. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +0 -2
  152. nautobot/project-static/docs/development/apps/api/views/index.html +0 -2
  153. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +0 -2
  154. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +0 -2
  155. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +0 -2
  156. nautobot/project-static/docs/development/apps/api/views/notes.html +0 -2
  157. nautobot/project-static/docs/development/apps/api/views/rest-api.html +0 -2
  158. nautobot/project-static/docs/development/apps/api/views/urls.html +0 -2
  159. nautobot/project-static/docs/development/apps/index.html +0 -2
  160. nautobot/project-static/docs/development/apps/migration/code-updates.html +0 -2
  161. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +1 -3
  162. nautobot/project-static/docs/development/apps/migration/from-v1.html +0 -2
  163. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +0 -2
  164. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +0 -2
  165. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +0 -2
  166. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +0 -2
  167. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +0 -2
  168. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +0 -2
  169. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +0 -2
  170. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +0 -2
  171. nautobot/project-static/docs/development/apps/porting-from-netbox.html +0 -2
  172. nautobot/project-static/docs/development/core/application-registry.html +0 -2
  173. nautobot/project-static/docs/development/core/best-practices.html +3 -5
  174. nautobot/project-static/docs/development/core/bootstrap-ui.html +0 -2
  175. nautobot/project-static/docs/development/core/caching.html +0 -2
  176. nautobot/project-static/docs/development/core/controllers.html +0 -2
  177. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +0 -2
  178. nautobot/project-static/docs/development/core/generic-views.html +0 -2
  179. nautobot/project-static/docs/development/core/getting-started.html +78 -109
  180. nautobot/project-static/docs/development/core/homepage.html +0 -2
  181. nautobot/project-static/docs/development/core/index.html +0 -2
  182. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +0 -2
  183. nautobot/project-static/docs/development/core/model-checklist.html +0 -2
  184. nautobot/project-static/docs/development/core/model-features.html +0 -2
  185. nautobot/project-static/docs/development/core/natural-keys.html +0 -2
  186. nautobot/project-static/docs/development/core/navigation-menu.html +0 -2
  187. nautobot/project-static/docs/development/core/release-checklist.html +1 -3
  188. nautobot/project-static/docs/development/core/role-internals.html +0 -2
  189. nautobot/project-static/docs/development/core/settings.html +0 -2
  190. nautobot/project-static/docs/development/core/style-guide.html +1 -3
  191. nautobot/project-static/docs/development/core/templates.html +0 -2
  192. nautobot/project-static/docs/development/core/testing.html +24 -200
  193. nautobot/project-static/docs/development/core/ui-component-framework.html +0 -2
  194. nautobot/project-static/docs/development/core/user-preferences.html +0 -2
  195. nautobot/project-static/docs/development/index.html +0 -2
  196. nautobot/project-static/docs/development/jobs/index.html +0 -2
  197. nautobot/project-static/docs/development/jobs/migration/from-v1.html +0 -2
  198. nautobot/project-static/docs/index.html +0 -2
  199. nautobot/project-static/docs/media/user-guide/administration/getting-started/nautobot-cloud.png +0 -0
  200. nautobot/project-static/docs/objects.inv +0 -0
  201. nautobot/project-static/docs/overview/application_stack.html +1 -3
  202. nautobot/project-static/docs/overview/design_philosophy.html +0 -2
  203. nautobot/project-static/docs/release-notes/index.html +0 -2
  204. nautobot/project-static/docs/release-notes/version-1.0.html +0 -2
  205. nautobot/project-static/docs/release-notes/version-1.1.html +0 -2
  206. nautobot/project-static/docs/release-notes/version-1.2.html +0 -2
  207. nautobot/project-static/docs/release-notes/version-1.3.html +0 -2
  208. nautobot/project-static/docs/release-notes/version-1.4.html +0 -2
  209. nautobot/project-static/docs/release-notes/version-1.5.html +0 -2
  210. nautobot/project-static/docs/release-notes/version-1.6.html +0 -2
  211. nautobot/project-static/docs/release-notes/version-2.0.html +0 -2
  212. nautobot/project-static/docs/release-notes/version-2.1.html +0 -2
  213. nautobot/project-static/docs/release-notes/version-2.2.html +0 -2
  214. nautobot/project-static/docs/release-notes/version-2.3.html +0 -2
  215. nautobot/project-static/docs/release-notes/version-2.4.html +364 -3
  216. nautobot/project-static/docs/search/search_index.json +1 -1
  217. nautobot/project-static/docs/sitemap.xml +290 -290
  218. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  219. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +0 -2
  220. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +0 -2
  221. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +0 -2
  222. nautobot/project-static/docs/user-guide/administration/configuration/index.html +0 -2
  223. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +0 -2
  224. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +2 -50
  225. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +0 -2
  226. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +0 -2
  227. nautobot/project-static/docs/user-guide/administration/guides/docker.html +0 -2
  228. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +0 -2
  229. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +71 -2
  230. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +0 -2
  231. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +0 -2
  232. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +0 -2
  233. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +0 -2
  234. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +0 -2
  235. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +0 -2
  236. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +0 -2
  237. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +3 -3
  238. nautobot/project-static/docs/user-guide/administration/installation/index.html +257 -18
  239. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +0 -2
  240. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +0 -2
  241. nautobot/project-static/docs/user-guide/administration/installation/services.html +0 -2
  242. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +0 -2
  243. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +0 -2
  244. nautobot/project-static/docs/user-guide/administration/security/index.html +0 -2
  245. nautobot/project-static/docs/user-guide/administration/security/notices.html +0 -2
  246. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +1 -3
  247. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +0 -2
  248. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +0 -2
  249. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +0 -2
  250. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +0 -2
  251. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +0 -2
  252. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +0 -2
  253. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +0 -2
  254. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +0 -2
  255. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +0 -2
  256. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -4
  257. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +0 -2
  258. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +0 -2
  259. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +0 -2
  260. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +0 -2
  261. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +0 -2
  262. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +0 -2
  263. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +0 -2
  264. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +0 -2
  265. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +0 -2
  266. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +0 -2
  267. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +0 -2
  268. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +0 -2
  269. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +0 -2
  270. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +0 -2
  271. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +0 -2
  272. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +0 -2
  273. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +0 -2
  274. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +0 -2
  275. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +0 -2
  276. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +0 -2
  277. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +0 -2
  278. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +0 -2
  279. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +0 -2
  280. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +0 -2
  281. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +0 -2
  282. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +0 -2
  283. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +0 -2
  284. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +0 -2
  285. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +0 -2
  286. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +0 -2
  287. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +0 -2
  288. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +0 -2
  289. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +0 -2
  290. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +0 -2
  291. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +0 -2
  292. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +0 -2
  293. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +0 -2
  294. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +0 -2
  295. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +0 -2
  296. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +0 -2
  297. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +0 -2
  298. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +0 -2
  299. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +0 -2
  300. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +0 -2
  301. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +0 -2
  302. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +0 -2
  303. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +0 -2
  304. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +0 -2
  305. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +0 -2
  306. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +0 -2
  307. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -2
  308. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +0 -2
  309. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +0 -2
  310. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +0 -2
  311. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +0 -2
  312. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +0 -2
  313. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +0 -2
  314. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +0 -2
  315. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +0 -2
  316. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +0 -2
  317. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +0 -2
  318. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +0 -2
  319. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +0 -2
  320. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +0 -2
  321. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +0 -2
  322. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +0 -2
  323. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +0 -2
  324. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +0 -2
  325. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +0 -2
  326. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +0 -2
  327. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +0 -2
  328. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +0 -2
  329. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +0 -2
  330. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +0 -2
  331. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +0 -2
  332. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +0 -2
  333. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +0 -2
  334. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +0 -2
  335. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +0 -2
  336. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -13
  337. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +0 -2
  338. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +8 -10
  339. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +1 -2
  340. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +0 -2
  341. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +40 -27
  342. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -6
  343. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +1 -3
  344. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +77 -7
  345. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +1 -3
  346. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +0 -3
  347. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +1 -3
  348. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +0 -2
  349. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +0 -2
  350. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +0 -2
  351. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +0 -2
  352. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -2
  353. nautobot/project-static/docs/user-guide/index.html +89 -4
  354. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +0 -2
  355. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +0 -2
  356. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +0 -2
  357. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +0 -2
  358. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +0 -2
  359. nautobot/project-static/docs/user-guide/platform-functionality/events.html +0 -2
  360. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +0 -2
  361. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +0 -2
  362. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +0 -2
  363. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +0 -2
  364. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +0 -2
  365. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +0 -2
  366. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +0 -2
  367. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +0 -2
  368. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +0 -2
  369. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +0 -2
  370. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +0 -2
  371. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -2
  372. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +0 -2
  373. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +0 -2
  374. nautobot/project-static/docs/user-guide/platform-functionality/note.html +0 -2
  375. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +0 -2
  376. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +0 -2
  377. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +0 -2
  378. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +0 -2
  379. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +0 -2
  380. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +0 -2
  381. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +0 -2
  382. nautobot/project-static/docs/user-guide/platform-functionality/role.html +0 -2
  383. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +0 -2
  384. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +0 -2
  385. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +0 -2
  386. nautobot/project-static/docs/user-guide/platform-functionality/status.html +0 -2
  387. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +0 -2
  388. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +0 -2
  389. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +0 -2
  390. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +0 -2
  391. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +207 -124
  392. nautobot/project-static/js/forms.js +88 -37
  393. nautobot/project-static/js/homepage_layout.js +12 -3
  394. nautobot/virtualization/forms.py +20 -0
  395. nautobot/virtualization/templates/virtualization/clustergroup.html +1 -39
  396. nautobot/virtualization/templates/virtualization/clustertype.html +1 -0
  397. nautobot/virtualization/tests/test_api.py +14 -3
  398. nautobot/virtualization/tests/test_views.py +10 -2
  399. nautobot/virtualization/urls.py +10 -93
  400. nautobot/virtualization/views.py +33 -72
  401. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/METADATA +6 -5
  402. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/RECORD +407 -402
  403. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/WHEEL +1 -1
  404. nautobot/core/tests/performance_baselines.yml +0 -8900
  405. nautobot/dcim/templates/dcim/modulebay_create.html +0 -39
  406. nautobot/ipam/tests/test_migrations.py +0 -462
  407. /nautobot/ipam/templates/ipam/{namespace_ipaddresses.html → namespace_ip_addresses.html} +0 -0
  408. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/LICENSE.txt +0 -0
  409. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/NOTICE +0 -0
  410. {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/entry_points.txt +0 -0
@@ -291,9 +291,9 @@ def get_table_class_string_from_view_name(view_name):
291
291
 
292
292
  view_func = resolve(reverse(view_name)).func
293
293
  view_class = getattr(view_func, "cls", getattr(view_func, "view_class", None))
294
- if hasattr(view_class, "table_class"):
294
+ if hasattr(view_class, "table_class") and view_class.table_class:
295
295
  return view_class.table_class.__name__
296
- if hasattr(view_class, "table"):
296
+ if hasattr(view_class, "table") and view_class.table:
297
297
  return view_class.table.__name__
298
298
  return None
299
299
 
nautobot/dcim/factory.py CHANGED
@@ -680,6 +680,7 @@ class SoftwareImageFileFactory(PrimaryModelFactory):
680
680
  has_hashing_algorithm = NautobotBoolIterator()
681
681
  has_image_file_size = NautobotBoolIterator()
682
682
  has_download_url = NautobotBoolIterator()
683
+ has_external_integration = NautobotBoolIterator()
683
684
 
684
685
  status = random_instance(
685
686
  lambda: Status.objects.get_for_model(SoftwareImageFile),
@@ -698,6 +699,7 @@ class SoftwareImageFileFactory(PrimaryModelFactory):
698
699
  default_image = factory.LazyAttribute(
699
700
  lambda o: not o.software_version.software_image_files.filter(default_image=True).exists()
700
701
  )
702
+ external_integration = factory.Maybe("has_external_integration", random_instance(ExternalIntegration))
701
703
 
702
704
 
703
705
  class SoftwareVersionFactory(PrimaryModelFactory):
@@ -1791,6 +1791,11 @@ class SoftwareImageFileFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1791
1791
  default_image = django_filters.BooleanFilter(
1792
1792
  label="Is default image for associated software version",
1793
1793
  )
1794
+ external_integration = NaturalKeyOrPKMultipleChoiceFilter(
1795
+ queryset=ExternalIntegration.objects.all(),
1796
+ to_field_name="name",
1797
+ label="External integration (name or ID)",
1798
+ )
1794
1799
 
1795
1800
  class Meta:
1796
1801
  model = SoftwareImageFile
nautobot/dcim/forms.py CHANGED
@@ -36,6 +36,7 @@ from nautobot.core.forms import (
36
36
  TagFilterField,
37
37
  )
38
38
  from nautobot.core.forms.constants import BOOLEAN_WITH_BLANK_CHOICES
39
+ from nautobot.core.forms.fields import LaxURLField
39
40
  from nautobot.dcim.form_mixins import (
40
41
  LocatableModelBulkEditFormMixin,
41
42
  LocatableModelFilterFormMixin,
@@ -767,6 +768,16 @@ class RackReservationFilterForm(NautobotFilterForm, TenancyFilterForm):
767
768
  #
768
769
 
769
770
 
771
+ class ManufacturerBulkEditForm(NautobotBulkEditForm):
772
+ pk = forms.ModelMultipleChoiceField(queryset=Manufacturer.objects.all(), widget=forms.MultipleHiddenInput())
773
+ description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
774
+
775
+ class Meta:
776
+ nullable_fields = [
777
+ "description",
778
+ ]
779
+
780
+
770
781
  class ManufacturerForm(NautobotModelForm):
771
782
  class Meta:
772
783
  model = Manufacturer
@@ -4773,7 +4784,11 @@ class SoftwareImageFileBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFo
4773
4784
  )
4774
4785
  image_file_size = forms.IntegerField(required=False)
4775
4786
  default_image = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label="Is default image")
4776
- download_url = forms.URLField(required=False)
4787
+ download_url = LaxURLField(required=False)
4788
+ external_integration = DynamicModelChoiceField(
4789
+ queryset=ExternalIntegration.objects.all(),
4790
+ required=False,
4791
+ )
4777
4792
 
4778
4793
  class Meta:
4779
4794
  model = SoftwareImageFile
@@ -4782,6 +4797,7 @@ class SoftwareImageFileBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFo
4782
4797
  "hashing_algorithm",
4783
4798
  "image_file_size",
4784
4799
  "download_url",
4800
+ "external_integration",
4785
4801
  ]
4786
4802
 
4787
4803
 
@@ -4816,6 +4832,10 @@ class SoftwareImageFileFilterForm(NautobotFilterForm, StatusModelFilterFormMixin
4816
4832
  label="Has device types",
4817
4833
  widget=StaticSelect2(choices=BOOLEAN_WITH_BLANK_CHOICES),
4818
4834
  )
4835
+ external_integration = DynamicModelChoiceField(
4836
+ queryset=ExternalIntegration.objects.all(),
4837
+ required=False,
4838
+ )
4819
4839
 
4820
4840
  tags = TagFilterField(model)
4821
4841
 
@@ -4829,6 +4849,7 @@ class SoftwareImageFileFilterForm(NautobotFilterForm, StatusModelFilterFormMixin
4829
4849
  "download_url",
4830
4850
  "device_types",
4831
4851
  "has_device_types",
4852
+ "external_integration",
4832
4853
  "status",
4833
4854
  "tags",
4834
4855
  ]
@@ -4843,6 +4864,11 @@ class SoftwareImageFileForm(NautobotModelForm):
4843
4864
  label="Device Types",
4844
4865
  )
4845
4866
 
4867
+ external_integration = DynamicModelChoiceField(
4868
+ queryset=ExternalIntegration.objects.all(),
4869
+ required=False,
4870
+ )
4871
+
4846
4872
  field_order = [
4847
4873
  "software_version",
4848
4874
  "image_file_name",
@@ -0,0 +1,19 @@
1
+ # Generated by Django 4.2.19 on 2025-03-06 19:34
2
+
3
+ from django.db import migrations
4
+
5
+ import nautobot.core.models.fields
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ dependencies = [
10
+ ("dcim", "0067_controllermanageddevicegroup_tenant"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name="softwareimagefile",
16
+ name="download_url",
17
+ field=nautobot.core.models.fields.LaxURLField(blank=True),
18
+ ),
19
+ ]
@@ -0,0 +1,25 @@
1
+ # Generated by Django 4.2.20 on 2025-03-11 19:10
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("extras", "0122_add_graphqlquery_owner_content_type"),
10
+ ("dcim", "0068_alter_softwareimagefile_download_url"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AddField(
15
+ model_name="softwareimagefile",
16
+ name="external_integration",
17
+ field=models.ForeignKey(
18
+ blank=True,
19
+ null=True,
20
+ on_delete=django.db.models.deletion.PROTECT,
21
+ related_name="software_image_files",
22
+ to="extras.externalintegration",
23
+ ),
24
+ ),
25
+ ]
@@ -14,7 +14,7 @@ import yaml
14
14
 
15
15
  from nautobot.core.constants import CHARFIELD_MAX_LENGTH
16
16
  from nautobot.core.models import BaseManager, RestrictedQuerySet
17
- from nautobot.core.models.fields import JSONArrayField, NaturalOrderingField
17
+ from nautobot.core.models.fields import JSONArrayField, LaxURLField, NaturalOrderingField
18
18
  from nautobot.core.models.generics import BaseModel, OrganizationalModel, PrimaryModel
19
19
  from nautobot.core.models.tree_queries import TreeModel
20
20
  from nautobot.core.utils.config import get_settings_or_config
@@ -1239,7 +1239,14 @@ class SoftwareImageFile(PrimaryModel):
1239
1239
  verbose_name="Image File Size",
1240
1240
  help_text="Image file size in bytes",
1241
1241
  )
1242
- download_url = models.URLField(blank=True, verbose_name="Download URL")
1242
+ download_url = LaxURLField(blank=True, verbose_name="Download URL")
1243
+ external_integration = models.ForeignKey(
1244
+ to="extras.ExternalIntegration",
1245
+ on_delete=models.PROTECT,
1246
+ related_name="software_image_files",
1247
+ blank=True,
1248
+ null=True,
1249
+ )
1243
1250
  default_image = models.BooleanField(
1244
1251
  verbose_name="Default Image", help_text="Is the default image for this software version", default=False
1245
1252
  )
@@ -220,6 +220,15 @@ class Location(TreeModel, PrimaryModel):
220
220
  def __str__(self):
221
221
  return self.name
222
222
 
223
+ @property
224
+ def display(self):
225
+ """
226
+ Honor LOCATION_NAME_AS_NATURAL_KEY for display value rendering, else fallback to TreeModel.display().
227
+ """
228
+ if get_settings_or_config("LOCATION_NAME_AS_NATURAL_KEY"):
229
+ return self.name
230
+ return super().display
231
+
223
232
  @classproperty # https://github.com/PyCQA/pylint-django/issues/240
224
233
  def natural_key_field_lookups(cls): # pylint: disable=no-self-argument
225
234
  """
@@ -1275,6 +1275,7 @@ class SoftwareImageFileTable(StatusTableMixin, BaseTable):
1275
1275
  "image_file_checksum",
1276
1276
  "hashing_algorithm",
1277
1277
  "download_url",
1278
+ "external_integration",
1278
1279
  "device_type_count",
1279
1280
  "tags",
1280
1281
  "actions",
@@ -3,7 +3,7 @@
3
3
  {% block bulk_buttons %}
4
4
  {% if perms.dcim.change_device %}
5
5
  <div class="btn-group dropup">
6
- <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
6
+ <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="device-bulk-add-components-button">
7
7
  <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
8
8
  </button>
9
9
  <ul class="dropdown-menu">
@@ -10,7 +10,7 @@
10
10
  {% block extra_buttons %}
11
11
  {% if perms.dcim.change_devicetype %}
12
12
  <div class="btn-group">
13
- <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
13
+ <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="device-type-add-components-button">
14
14
  <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
15
15
  </button>
16
16
  <ul class="dropdown-menu">
@@ -1,64 +1,2 @@
1
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>Manufacturer</strong>
8
- </div>
9
- <table class="table table-hover panel-body attr-table">
10
- <tr>
11
- <td>Description</td>
12
- <td>{{ object.description|placeholder }}</td>
13
- </tr>
14
- <tr>
15
- <td>Devices</td>
16
- <td>
17
- <a href="{% url 'dcim:device_list' %}?manufacturer={{ object.name }}">{{ device_table.rows|length }}</a>
18
- </td>
19
- </tr>
20
- {% if cloud_account_table.rows %}
21
- <tr>
22
- <td>Cloud Accounts</td>
23
- <td>
24
- <a href="{% url 'cloud:cloudaccount_list' %}?provider={{ object.name }}">{{ cloud_account_table.rows|length }}</a>
25
- </td>
26
- </tr>
27
- {% endif %}
28
- </table>
29
- </div>
30
- {% endblock content_left_page %}
31
-
32
- {% block content_full_width_page %}
33
- <div class="panel panel-default">
34
- <div class="panel-heading">
35
- <strong>Devices</strong>
36
- </div>
37
- {% include 'inc/table.html' with table=device_table %}
38
- {% if perms.dcim.add_device %}
39
- <div class="panel-footer text-right noprint">
40
- <a href="{% url 'dcim:device_add' %}?manufacturer={{ object.pk }}" class="btn btn-xs btn-primary">
41
- <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add device
42
- </a>
43
- </div>
44
- {% endif %}
45
- </div>
46
- {% include 'inc/paginator.html' with paginator=device_table.paginator page=device_table.page %}
47
- {% if cloud_account_table.rows %}
48
- <div class="panel panel-default">
49
- <div class="panel-heading">
50
- <strong>Cloud Accounts</strong>
51
- </div>
52
- {% include 'inc/table.html' with table=cloud_account_table %}
53
- {% if perms.cloud.add_cloudaccount %}
54
- <div class="panel-footer text-right noprint">
55
- <a href="{% url 'cloud:cloudaccount_add' %}?provider={{ object.pk }}" class="btn btn-xs btn-primary">
56
- <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Cloud Account
57
- </a>
58
- </div>
59
- {% endif %}
60
- </div>
61
- {% include 'inc/paginator.html' with paginator=cloud_account_table.paginator page=cloud_account_table.page %}
62
- {% endif %}
63
- <div class="row"></div>
64
- {% endblock content_full_width_page %}
2
+ {% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
@@ -3,7 +3,7 @@
3
3
  {% block bulk_buttons %}
4
4
  {% if perms.dcim.change_module %}
5
5
  <div class="btn-group dropup">
6
- <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
6
+ <button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="module-bulk-add-components-button">
7
7
  <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
8
8
  </button>
9
9
  <ul class="dropdown-menu">
@@ -9,7 +9,7 @@
9
9
  {% block extra_buttons %}
10
10
  {% if perms.dcim.change_moduletype %}
11
11
  <div class="btn-group">
12
- <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
12
+ <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="module-type-add-components-button">
13
13
  <span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Components <span class="caret"></span>
14
14
  </button>
15
15
  <ul class="dropdown-menu">
@@ -100,6 +100,10 @@
100
100
  {% endwith %}
101
101
  </td>
102
102
  </tr>
103
+ <tr>
104
+ <td>External Integration</td>
105
+ <td>{{ object.external_integration|hyperlinked_object }}</td>
106
+ </tr>
103
107
  <tr>
104
108
  <td>Devices overridden to use this file</td>
105
109
  <td>
@@ -0,0 +1,125 @@
1
+ from django.urls import reverse
2
+
3
+ from nautobot.core.testing.integration import ObjectsListMixin, SeleniumTestCase
4
+ from nautobot.dcim.models import DeviceType, Manufacturer, Module, ModuleBay, ModuleType
5
+ from nautobot.extras.models import Status
6
+ from nautobot.extras.tests.integration import create_test_device
7
+
8
+
9
+ class ModuleBayPositionTestCase(SeleniumTestCase, ObjectsListMixin):
10
+ """
11
+ Test creating a module bay component in device and device type.
12
+ """
13
+
14
+ def _validate_position_field(self):
15
+ # Fill name pattern
16
+ name_pattern_field = self.browser.find_by_css("#id_name_pattern")
17
+ name_pattern_value = "name-0/0/[0-9]"
18
+ for _ in name_pattern_field.type(name_pattern_value, slowly=True):
19
+ pass
20
+
21
+ # Verify that position is filled
22
+ position_field = self.browser.find_by_css("#id_position_pattern")
23
+ self.assertEqual(position_field.value, name_pattern_value, "Position field value is not properly set")
24
+
25
+ # Change pattern manually and name to verify if it's not updating then
26
+ position_field.fill("")
27
+ for _ in position_field.type("new pattern", slowly=True):
28
+ pass
29
+
30
+ for _ in name_pattern_field.type("v2", slowly=True):
31
+ pass
32
+
33
+ self.assertEqual(position_field.value, "new pattern", "Position field value has unexpectedly changed")
34
+
35
+ # Regenerate position
36
+ self.browser.find_by_css('button[data-original-title="Regenerate position"]').click()
37
+ self.assertEqual(position_field.value, f"{name_pattern_value}v2", "Position field value is not re-populated")
38
+
39
+ def test_create_device_type_module_bay(self):
40
+ self.login_as_superuser()
41
+
42
+ manufacturer, _ = Manufacturer.objects.get_or_create(
43
+ name="Test Manufacturer",
44
+ )
45
+ device_type, _ = DeviceType.objects.get_or_create(manufacturer=manufacturer, model="Test Model Module Bay")
46
+
47
+ details_url = self.live_server_url + reverse("dcim:devicetype", kwargs={"pk": device_type.pk})
48
+ self.browser.visit(details_url)
49
+
50
+ # Navigate to module bay create page
51
+ self.browser.find_by_css("#device-type-add-components-button").click()
52
+ self.browser.find_by_xpath(
53
+ "//*[@id='device-type-add-components-button']/following-sibling::*//a[normalize-space()='Module Bays']"
54
+ ).click()
55
+
56
+ self._validate_position_field()
57
+
58
+ def test_create_device_module_bay(self):
59
+ self.login_as_superuser()
60
+
61
+ device = create_test_device("Test Device Module Bay Integration Test 1")
62
+ details_url = self.live_server_url + reverse("dcim:device", kwargs={"pk": device.pk})
63
+ self.browser.visit(details_url)
64
+
65
+ # Navigate to module bay create page
66
+ self.browser.find_by_css("#device-add-components-button").click()
67
+ self.browser.find_by_xpath(
68
+ "//*[@id='device-add-components-button']/following-sibling::*//a[normalize-space()='Module Bays']"
69
+ ).click()
70
+
71
+ self._validate_position_field()
72
+
73
+ def test_bulk_create_device_module_bay(self):
74
+ self.login_as_superuser()
75
+
76
+ device = create_test_device("Test Device Module Bay Integration Test 1", test_uuid="a15a58b0b")
77
+ self.browser.visit(self.live_server_url + reverse("dcim:device_list"))
78
+
79
+ self.apply_filter("location", "a15a58b0b")
80
+
81
+ self.select_one_item(pk=device.pk)
82
+ self.browser.find_by_css("#device-bulk-add-components-button").click()
83
+ self.browser.find_by_xpath(
84
+ "//*[@id='device-bulk-add-components-button']/following-sibling::*//a[normalize-space()='Module Bays']"
85
+ ).click()
86
+
87
+ self._validate_position_field()
88
+
89
+ def test_create_module_type_module_bay(self):
90
+ self.login_as_superuser()
91
+
92
+ manufacturer, _ = Manufacturer.objects.get_or_create(name="Test Manufacturer")
93
+ module_type = ModuleType.objects.create(model="Module_Type", manufacturer=manufacturer)
94
+
95
+ details_url = self.live_server_url + reverse("dcim:moduletype", kwargs={"pk": module_type.pk})
96
+ self.browser.visit(details_url)
97
+
98
+ self.browser.find_by_css("#module-type-add-components-button").click()
99
+ self.browser.find_by_xpath(
100
+ "//*[@id='module-type-add-components-button']/following-sibling::*//a[normalize-space()='Module Bays']"
101
+ ).click()
102
+
103
+ self._validate_position_field()
104
+
105
+ def test_bulk_create_module_module_bay(self):
106
+ self.login_as_superuser()
107
+
108
+ device = create_test_device("Test Device Module Bay Integration Test 2", test_uuid="60a7d5e")
109
+ module_type = ModuleType.objects.create(model="Module_Type", manufacturer=device.device_type.manufacturer)
110
+ device_module_bay = ModuleBay.objects.create(parent_device=device, name="Test Bay")
111
+ module = Module.objects.create(
112
+ module_type=module_type,
113
+ status=Status.objects.get_for_model(Module).first(),
114
+ parent_module_bay=device_module_bay,
115
+ )
116
+
117
+ self.browser.visit(self.live_server_url + reverse("dcim:module_list"))
118
+ self.select_one_item(pk=module.pk)
119
+
120
+ self.browser.find_by_css("#module-bulk-add-components-button").click()
121
+ self.browser.find_by_xpath(
122
+ "//*[@id='module-bulk-add-components-button']/following-sibling::*//a[normalize-space()='Module Bays']"
123
+ ).click()
124
+
125
+ self._validate_position_field()