nautobot 2.4.14__py3-none-any.whl → 2.4.15__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 (433) hide show
  1. nautobot/apps/choices.py +8 -0
  2. nautobot/apps/ui.py +14 -0
  3. nautobot/core/api/views.py +2 -0
  4. nautobot/core/choices.py +4 -0
  5. nautobot/core/filters.py +21 -41
  6. nautobot/core/management/commands/check_job_approval_status.py +47 -0
  7. nautobot/core/management/commands/generate_test_data.py +1 -1
  8. nautobot/core/management/commands/migrate.py +1 -1
  9. nautobot/core/models/tree_queries.py +17 -0
  10. nautobot/core/settings.py +2 -2
  11. nautobot/core/tables.py +25 -2
  12. nautobot/core/templates/base_django.html +1 -1
  13. nautobot/core/templates/components/panel/header_extra_content_table.html +1 -1
  14. nautobot/core/templates/generic/object_list.html +17 -20
  15. nautobot/core/templates/inc/breadcrumbs.html +14 -0
  16. nautobot/core/templatetags/buttons.py +2 -4
  17. nautobot/core/templatetags/helpers.py +29 -6
  18. nautobot/core/templatetags/ui_framework.py +21 -0
  19. nautobot/core/testing/filters.py +20 -3
  20. nautobot/core/testing/forms.py +1 -1
  21. nautobot/core/tests/integration/test_filters.py +2 -2
  22. nautobot/core/tests/test_breadcrumbs.py +366 -0
  23. nautobot/core/tests/test_commands.py +40 -0
  24. nautobot/core/tests/test_filters.py +51 -1
  25. nautobot/core/tests/test_forms.py +1 -1
  26. nautobot/core/tests/test_graphql.py +4 -4
  27. nautobot/core/tests/test_titles.py +183 -0
  28. nautobot/core/tests/test_tree_queries.py +30 -0
  29. nautobot/core/tests/test_views.py +2 -2
  30. nautobot/core/tests/test_views_utils.py +1 -1
  31. nautobot/core/ui/breadcrumbs.py +538 -0
  32. nautobot/core/ui/bulk_buttons.py +53 -0
  33. nautobot/core/ui/object_detail.py +31 -8
  34. nautobot/core/ui/titles.py +127 -0
  35. nautobot/core/ui/utils.py +25 -0
  36. nautobot/core/utils/migrations.py +1 -1
  37. nautobot/core/views/__init__.py +1 -1
  38. nautobot/core/views/mixins.py +26 -1
  39. nautobot/core/views/renderers.py +20 -2
  40. nautobot/core/views/utils.py +13 -12
  41. nautobot/dcim/api/serializers.py +9 -0
  42. nautobot/dcim/choices.py +53 -0
  43. nautobot/dcim/filters/__init__.py +15 -3
  44. nautobot/dcim/forms.py +120 -7
  45. nautobot/dcim/management/commands/trace_paths.py +1 -1
  46. nautobot/dcim/migrations/0072_alter_powerfeed_options_and_more.py +97 -0
  47. nautobot/dcim/models/device_component_templates.py +8 -0
  48. nautobot/dcim/models/device_components.py +31 -12
  49. nautobot/dcim/models/devices.py +1 -1
  50. nautobot/dcim/models/power.py +171 -10
  51. nautobot/dcim/models/racks.py +7 -4
  52. nautobot/dcim/tables/devices.py +2 -0
  53. nautobot/dcim/tables/devicetypes.py +1 -0
  54. nautobot/dcim/tables/power.py +30 -2
  55. nautobot/dcim/templates/dcim/device.html +2 -2
  56. nautobot/dcim/templates/dcim/devicetype_retrieve.html +1 -214
  57. nautobot/dcim/templates/dcim/location_retrieve.html +2 -2
  58. nautobot/dcim/templates/dcim/powerfeed_edit.html +8 -0
  59. nautobot/dcim/templates/dcim/powerfeed_retrieve.html +1 -1
  60. nautobot/dcim/tests/integration/test_device_bulk_operations.py +61 -0
  61. nautobot/dcim/tests/test_api.py +24 -4
  62. nautobot/dcim/tests/test_filters.py +91 -13
  63. nautobot/dcim/tests/test_models.py +262 -0
  64. nautobot/dcim/tests/test_views.py +20 -12
  65. nautobot/dcim/utils.py +9 -0
  66. nautobot/dcim/views.py +390 -77
  67. nautobot/extras/factory.py +19 -20
  68. nautobot/extras/filters/__init__.py +3 -2
  69. nautobot/extras/filters/mixins.py +15 -1
  70. nautobot/extras/forms/__init__.py +2 -1
  71. nautobot/extras/forms/forms.py +62 -0
  72. nautobot/extras/managers.py +4 -1
  73. nautobot/extras/migrations/0125_jobresult_date_started.py +18 -0
  74. nautobot/extras/models/customfields.py +1 -2
  75. nautobot/extras/models/datasources.py +1 -2
  76. nautobot/extras/models/jobs.py +7 -3
  77. nautobot/extras/plugins/views.py +24 -1
  78. nautobot/extras/secrets/__init__.py +1 -1
  79. nautobot/extras/tables.py +9 -0
  80. nautobot/extras/templates/extras/customfield.html +2 -129
  81. nautobot/extras/templates/extras/customfield_edit.html +2 -108
  82. nautobot/extras/templates/extras/customfield_retrieve.html +129 -0
  83. nautobot/extras/templates/extras/customfield_update.html +108 -0
  84. nautobot/extras/templates/extras/inc/jobresult.html +7 -3
  85. nautobot/extras/templates/extras/jobresult.html +2 -155
  86. nautobot/extras/templates/extras/jobresult_retrieve.html +155 -0
  87. nautobot/extras/templates/extras/marketplace.html +5 -6
  88. nautobot/extras/templates/extras/note.html +2 -53
  89. nautobot/extras/templates/extras/note_retrieve.html +53 -0
  90. nautobot/extras/templates/extras/plugins_list.html +5 -6
  91. nautobot/extras/templatetags/custom_links.py +2 -2
  92. nautobot/extras/templatetags/job_buttons.py +1 -1
  93. nautobot/extras/templatetags/plugins.py +1 -1
  94. nautobot/extras/tests/integration/test_computedfields.py +2 -2
  95. nautobot/extras/tests/integration/test_customfields.py +14 -11
  96. nautobot/extras/tests/integration/test_dynamicgroups.py +1 -1
  97. nautobot/extras/tests/integration/test_notes.py +1 -1
  98. nautobot/extras/tests/integration/test_plugins.py +6 -6
  99. nautobot/extras/tests/integration/test_relationships.py +2 -2
  100. nautobot/extras/tests/test_filters.py +9 -0
  101. nautobot/extras/tests/test_forms.py +2 -2
  102. nautobot/extras/tests/test_plugins.py +2 -3
  103. nautobot/extras/tests/test_relationships.py +7 -7
  104. nautobot/extras/tests/test_views.py +172 -1
  105. nautobot/extras/urls.py +3 -59
  106. nautobot/extras/utils.py +1 -1
  107. nautobot/extras/views.py +77 -178
  108. nautobot/ipam/tables.py +8 -15
  109. nautobot/ipam/tests/migration/test_migrations.py +8 -8
  110. nautobot/ipam/tests/test_api.py +2 -2
  111. nautobot/ipam/tests/test_models.py +1 -1
  112. nautobot/project-static/docs/404.html +23 -0
  113. nautobot/project-static/docs/apps/index.html +23 -0
  114. nautobot/project-static/docs/apps/nautobot-apps.html +23 -0
  115. nautobot/project-static/docs/assets/_mkdocstrings.css +44 -6
  116. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +28 -0
  117. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +25 -0
  118. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +128 -20
  119. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +37 -4
  120. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +39 -6
  121. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +25 -0
  122. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +24 -0
  123. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +32 -5
  124. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +41 -8
  125. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +39 -7
  126. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +43 -10
  127. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +74 -59
  128. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +143 -28
  129. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +43 -12
  130. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +135 -53
  131. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +229 -36
  132. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +27 -1
  133. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +30 -1
  134. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +162 -18
  135. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +258 -51
  136. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5987 -2620
  137. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +25 -0
  138. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +154 -55
  139. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +150 -35
  140. nautobot/project-static/docs/development/apps/api/configuration-view.html +23 -0
  141. nautobot/project-static/docs/development/apps/api/database-backend-config.html +23 -0
  142. nautobot/project-static/docs/development/apps/api/models/django-admin.html +23 -0
  143. nautobot/project-static/docs/development/apps/api/models/global-search.html +23 -0
  144. nautobot/project-static/docs/development/apps/api/models/graphql.html +23 -0
  145. nautobot/project-static/docs/development/apps/api/models/index.html +23 -0
  146. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +23 -0
  147. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +23 -0
  148. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +23 -0
  149. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +23 -0
  150. nautobot/project-static/docs/development/apps/api/platform-features/index.html +23 -0
  151. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +23 -0
  152. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +23 -0
  153. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +23 -0
  154. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +23 -0
  155. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +23 -0
  156. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +23 -0
  157. nautobot/project-static/docs/development/apps/api/prometheus.html +23 -0
  158. nautobot/project-static/docs/development/apps/api/setup.html +23 -0
  159. nautobot/project-static/docs/development/apps/api/testing.html +23 -0
  160. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +23 -0
  161. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +23 -0
  162. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +23 -0
  163. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +23 -0
  164. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +23 -0
  165. nautobot/project-static/docs/development/apps/api/views/base-template.html +23 -0
  166. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +23 -0
  167. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +23 -0
  168. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +23 -0
  169. nautobot/project-static/docs/development/apps/api/views/index.html +23 -0
  170. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +23 -0
  171. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +31 -2
  172. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +23 -0
  173. nautobot/project-static/docs/development/apps/api/views/notes.html +23 -0
  174. nautobot/project-static/docs/development/apps/api/views/rest-api.html +23 -0
  175. nautobot/project-static/docs/development/apps/api/views/urls.html +23 -0
  176. nautobot/project-static/docs/development/apps/index.html +23 -0
  177. nautobot/project-static/docs/development/apps/migration/code-updates.html +23 -0
  178. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +23 -0
  179. nautobot/project-static/docs/development/apps/migration/from-v1.html +23 -0
  180. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +23 -0
  181. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +23 -0
  182. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +23 -0
  183. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +23 -0
  184. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +26 -3
  185. nautobot/project-static/docs/development/apps/migration/ui-component-framework/breadcrumbs-titles.html +10544 -0
  186. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +23 -0
  187. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +23 -0
  188. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +23 -0
  189. nautobot/project-static/docs/development/apps/porting-from-netbox.html +26 -3
  190. nautobot/project-static/docs/development/core/application-registry.html +23 -0
  191. nautobot/project-static/docs/development/core/best-practices.html +23 -0
  192. nautobot/project-static/docs/development/core/bootstrap-ui.html +23 -0
  193. nautobot/project-static/docs/development/core/caching.html +23 -0
  194. nautobot/project-static/docs/development/core/controllers.html +23 -0
  195. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +23 -0
  196. nautobot/project-static/docs/development/core/generic-views.html +23 -0
  197. nautobot/project-static/docs/development/core/getting-started.html +23 -0
  198. nautobot/project-static/docs/development/core/homepage.html +23 -0
  199. nautobot/project-static/docs/development/core/index.html +23 -0
  200. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +23 -0
  201. nautobot/project-static/docs/development/core/model-checklist.html +23 -0
  202. nautobot/project-static/docs/development/core/model-features.html +23 -0
  203. nautobot/project-static/docs/development/core/natural-keys.html +23 -0
  204. nautobot/project-static/docs/development/core/navigation-menu.html +23 -0
  205. nautobot/project-static/docs/development/core/release-checklist.html +23 -0
  206. nautobot/project-static/docs/development/core/role-internals.html +23 -0
  207. nautobot/project-static/docs/development/core/settings.html +23 -0
  208. nautobot/project-static/docs/development/core/style-guide.html +23 -0
  209. nautobot/project-static/docs/development/core/templates.html +23 -0
  210. nautobot/project-static/docs/development/core/testing.html +23 -0
  211. nautobot/project-static/docs/development/core/ui-component-framework.html +713 -255
  212. nautobot/project-static/docs/development/core/user-preferences.html +23 -0
  213. nautobot/project-static/docs/development/index.html +23 -0
  214. nautobot/project-static/docs/development/jobs/getting-started.html +23 -0
  215. nautobot/project-static/docs/development/jobs/index.html +23 -0
  216. nautobot/project-static/docs/development/jobs/installation.html +23 -0
  217. nautobot/project-static/docs/development/jobs/job-extensions.html +23 -0
  218. nautobot/project-static/docs/development/jobs/job-logging.html +23 -0
  219. nautobot/project-static/docs/development/jobs/job-patterns.html +23 -0
  220. nautobot/project-static/docs/development/jobs/job-structure.html +23 -0
  221. nautobot/project-static/docs/development/jobs/migration/from-v1.html +23 -0
  222. nautobot/project-static/docs/development/jobs/testing.html +23 -0
  223. nautobot/project-static/docs/index.html +23 -0
  224. nautobot/project-static/docs/media/development/core/ui-component-framework/breadcrumbs-titles-data-flow.png +0 -0
  225. nautobot/project-static/docs/media/power_distribution.png +0 -0
  226. nautobot/project-static/docs/objects.inv +0 -0
  227. nautobot/project-static/docs/overview/application_stack.html +23 -0
  228. nautobot/project-static/docs/overview/design_philosophy.html +23 -0
  229. nautobot/project-static/docs/release-notes/index.html +23 -0
  230. nautobot/project-static/docs/release-notes/version-1.0.html +23 -0
  231. nautobot/project-static/docs/release-notes/version-1.1.html +23 -0
  232. nautobot/project-static/docs/release-notes/version-1.2.html +23 -0
  233. nautobot/project-static/docs/release-notes/version-1.3.html +23 -0
  234. nautobot/project-static/docs/release-notes/version-1.4.html +23 -0
  235. nautobot/project-static/docs/release-notes/version-1.5.html +23 -0
  236. nautobot/project-static/docs/release-notes/version-1.6.html +23 -0
  237. nautobot/project-static/docs/release-notes/version-2.0.html +23 -0
  238. nautobot/project-static/docs/release-notes/version-2.1.html +23 -0
  239. nautobot/project-static/docs/release-notes/version-2.2.html +23 -0
  240. nautobot/project-static/docs/release-notes/version-2.3.html +23 -0
  241. nautobot/project-static/docs/release-notes/version-2.4.html +231 -0
  242. nautobot/project-static/docs/requirements.txt +2 -2
  243. nautobot/project-static/docs/search/search_index.json +1 -1
  244. nautobot/project-static/docs/sitemap.xml +303 -299
  245. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  246. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +23 -0
  247. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +23 -0
  248. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +23 -0
  249. nautobot/project-static/docs/user-guide/administration/configuration/index.html +23 -0
  250. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +23 -0
  251. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +23 -0
  252. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +23 -0
  253. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +23 -0
  254. nautobot/project-static/docs/user-guide/administration/guides/docker.html +23 -0
  255. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +23 -0
  256. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +23 -0
  257. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +23 -0
  258. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +23 -0
  259. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +23 -0
  260. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +23 -0
  261. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +23 -0
  262. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +23 -0
  263. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +23 -0
  264. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +23 -0
  265. nautobot/project-static/docs/user-guide/administration/installation/index.html +23 -0
  266. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +23 -0
  267. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +23 -0
  268. nautobot/project-static/docs/user-guide/administration/installation/services.html +23 -0
  269. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +23 -0
  270. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +23 -0
  271. nautobot/project-static/docs/user-guide/administration/security/index.html +23 -0
  272. nautobot/project-static/docs/user-guide/administration/security/notices.html +23 -0
  273. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +284 -219
  274. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +23 -0
  275. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +23 -0
  276. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +23 -0
  277. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +23 -0
  278. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +23 -0
  279. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +23 -0
  280. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +23 -0
  281. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +23 -0
  282. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +23 -0
  283. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +23 -0
  284. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +23 -0
  285. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +23 -0
  286. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +23 -0
  287. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +23 -0
  288. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +23 -0
  289. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +23 -0
  290. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +23 -0
  291. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +23 -0
  292. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +23 -0
  293. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +23 -0
  294. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +23 -0
  295. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +23 -0
  296. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +23 -0
  297. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +23 -0
  298. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +23 -0
  299. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +23 -0
  300. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +23 -0
  301. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +23 -0
  302. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +23 -0
  303. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +23 -0
  304. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +23 -0
  305. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +23 -0
  306. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +23 -0
  307. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +23 -0
  308. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +23 -0
  309. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +23 -0
  310. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +23 -0
  311. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +23 -0
  312. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +23 -0
  313. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +23 -0
  314. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +23 -0
  315. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +23 -0
  316. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +23 -0
  317. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +23 -0
  318. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +23 -0
  319. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +23 -0
  320. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +23 -0
  321. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +23 -0
  322. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +23 -0
  323. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +23 -0
  324. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +305 -5
  325. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +24 -1
  326. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +23 -0
  327. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +136 -3
  328. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +41 -1
  329. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +40 -0
  330. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +23 -0
  331. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +23 -0
  332. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +23 -0
  333. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +23 -0
  334. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +23 -0
  335. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +23 -0
  336. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +23 -0
  337. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +23 -0
  338. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +23 -0
  339. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +23 -0
  340. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +23 -0
  341. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +23 -0
  342. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +23 -0
  343. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +23 -0
  344. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +23 -0
  345. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +23 -0
  346. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +23 -0
  347. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +23 -0
  348. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +23 -0
  349. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +23 -0
  350. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +23 -0
  351. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +23 -0
  352. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +23 -0
  353. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +23 -0
  354. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +23 -0
  355. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +23 -0
  356. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +23 -0
  357. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +23 -0
  358. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +23 -0
  359. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +23 -0
  360. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +23 -0
  361. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +23 -0
  362. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +23 -0
  363. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +23 -0
  364. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +23 -0
  365. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +23 -0
  366. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +23 -0
  367. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +23 -0
  368. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +23 -0
  369. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +23 -0
  370. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +23 -0
  371. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +23 -0
  372. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +23 -0
  373. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +23 -0
  374. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +23 -0
  375. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +23 -0
  376. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +23 -0
  377. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +23 -0
  378. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +23 -0
  379. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +23 -0
  380. nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +23 -0
  381. nautobot/project-static/docs/user-guide/index.html +23 -0
  382. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +23 -0
  383. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +23 -0
  384. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +23 -0
  385. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +23 -0
  386. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +23 -0
  387. nautobot/project-static/docs/user-guide/platform-functionality/events.html +23 -0
  388. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +23 -0
  389. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +23 -0
  390. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +23 -0
  391. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +23 -0
  392. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +23 -0
  393. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +23 -0
  394. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +23 -0
  395. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +24 -1
  396. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +23 -0
  397. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +23 -0
  398. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +23 -0
  399. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +23 -0
  400. nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +23 -0
  401. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +23 -0
  402. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +23 -0
  403. nautobot/project-static/docs/user-guide/platform-functionality/note.html +23 -0
  404. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +23 -0
  405. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +23 -0
  406. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +23 -0
  407. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +23 -0
  408. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +23 -0
  409. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +23 -0
  410. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +23 -0
  411. nautobot/project-static/docs/user-guide/platform-functionality/role.html +23 -0
  412. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +23 -0
  413. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +23 -0
  414. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +23 -0
  415. nautobot/project-static/docs/user-guide/platform-functionality/status.html +23 -0
  416. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +23 -0
  417. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +23 -0
  418. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +23 -0
  419. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +23 -0
  420. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +23 -0
  421. nautobot/users/tests/test_api.py +2 -2
  422. nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -252
  423. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -75
  424. nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +252 -0
  425. nautobot/virtualization/templates/virtualization/virtualmachine_update.html +75 -0
  426. nautobot/virtualization/urls.py +3 -61
  427. nautobot/virtualization/views.py +48 -72
  428. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/METADATA +24 -24
  429. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/RECORD +433 -416
  430. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/LICENSE.txt +0 -0
  431. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/NOTICE +0 -0
  432. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/WHEEL +0 -0
  433. {nautobot-2.4.14.dist-info → nautobot-2.4.15.dist-info}/entry_points.txt +0 -0
nautobot/dcim/forms.py CHANGED
@@ -88,11 +88,14 @@ from .choices import (
88
88
  InterfaceTypeChoices,
89
89
  LocationDataToContactActionChoices,
90
90
  PortTypeChoices,
91
+ PowerFeedBreakerPoleChoices,
91
92
  PowerFeedPhaseChoices,
92
93
  PowerFeedSupplyChoices,
93
94
  PowerFeedTypeChoices,
94
95
  PowerOutletFeedLegChoices,
95
96
  PowerOutletTypeChoices,
97
+ PowerPanelTypeChoices,
98
+ PowerPathChoices,
96
99
  PowerPortTypeChoices,
97
100
  RackDimensionUnitChoices,
98
101
  RackTypeChoices,
@@ -1292,6 +1295,7 @@ class PowerPortTemplateForm(ModularComponentTemplateForm):
1292
1295
  "type",
1293
1296
  "maximum_draw",
1294
1297
  "allocated_draw",
1298
+ "power_factor",
1295
1299
  "description",
1296
1300
  ]
1297
1301
 
@@ -1300,6 +1304,15 @@ class PowerPortTemplateCreateForm(ModularComponentTemplateCreateForm):
1300
1304
  type = forms.ChoiceField(choices=add_blank_choice(PowerPortTypeChoices), required=False)
1301
1305
  maximum_draw = forms.IntegerField(min_value=1, required=False, help_text="Maximum power draw (watts)")
1302
1306
  allocated_draw = forms.IntegerField(min_value=1, required=False, help_text="Allocated power draw (watts)")
1307
+ power_factor = forms.DecimalField(
1308
+ max_digits=4,
1309
+ decimal_places=2,
1310
+ min_value=0.01,
1311
+ max_value=1.00,
1312
+ required=False,
1313
+ initial=0.95,
1314
+ help_text="Power factor (0.01-1.00) for converting between watts (W) and volt-amps (VA).",
1315
+ )
1303
1316
  field_order = (
1304
1317
  "device_type",
1305
1318
  "module_family",
@@ -1309,7 +1322,9 @@ class PowerPortTemplateCreateForm(ModularComponentTemplateCreateForm):
1309
1322
  "type",
1310
1323
  "maximum_draw",
1311
1324
  "allocated_draw",
1325
+ "power_factor",
1312
1326
  "description",
1327
+ "tags",
1313
1328
  )
1314
1329
 
1315
1330
 
@@ -1323,6 +1338,14 @@ class PowerPortTemplateBulkEditForm(NautobotBulkEditForm):
1323
1338
  )
1324
1339
  maximum_draw = forms.IntegerField(min_value=1, required=False, help_text="Maximum power draw (watts)")
1325
1340
  allocated_draw = forms.IntegerField(min_value=1, required=False, help_text="Allocated power draw (watts)")
1341
+ power_factor = forms.DecimalField(
1342
+ max_digits=4,
1343
+ decimal_places=2,
1344
+ min_value=0.01,
1345
+ max_value=1.00,
1346
+ required=False,
1347
+ help_text="Power factor (0.01-1.00) for converting between watts and VA.",
1348
+ )
1326
1349
  description = forms.CharField(required=False)
1327
1350
 
1328
1351
  class Meta:
@@ -1898,6 +1921,7 @@ class PowerPortTemplateImportForm(ComponentTemplateImportForm):
1898
1921
  "type",
1899
1922
  "maximum_draw",
1900
1923
  "allocated_draw",
1924
+ "power_factor",
1901
1925
  ]
1902
1926
 
1903
1927
 
@@ -2906,6 +2930,7 @@ class PowerPortForm(ModularComponentEditForm):
2906
2930
  "type",
2907
2931
  "maximum_draw",
2908
2932
  "allocated_draw",
2933
+ "power_factor",
2909
2934
  "description",
2910
2935
  "tags",
2911
2936
  ]
@@ -2919,6 +2944,15 @@ class PowerPortCreateForm(ModularComponentCreateForm):
2919
2944
  )
2920
2945
  maximum_draw = forms.IntegerField(min_value=1, required=False, help_text="Maximum draw in watts")
2921
2946
  allocated_draw = forms.IntegerField(min_value=1, required=False, help_text="Allocated draw in watts")
2947
+ power_factor = forms.DecimalField(
2948
+ max_digits=4,
2949
+ decimal_places=2,
2950
+ min_value=0.01,
2951
+ max_value=1.00,
2952
+ required=False,
2953
+ initial=0.95,
2954
+ help_text="Power factor (0.01-1.00) for converting between watts and VA.",
2955
+ )
2922
2956
  field_order = (
2923
2957
  "device",
2924
2958
  "module_family",
@@ -2928,13 +2962,14 @@ class PowerPortCreateForm(ModularComponentCreateForm):
2928
2962
  "type",
2929
2963
  "maximum_draw",
2930
2964
  "allocated_draw",
2965
+ "power_factor",
2931
2966
  "description",
2932
2967
  "tags",
2933
2968
  )
2934
2969
 
2935
2970
 
2936
2971
  class PowerPortBulkCreateForm(
2937
- form_from_model(PowerPort, ["type", "maximum_draw", "allocated_draw", "tags"]),
2972
+ form_from_model(PowerPort, ["type", "maximum_draw", "allocated_draw", "power_factor", "tags"]),
2938
2973
  DeviceBulkAddComponentForm,
2939
2974
  ):
2940
2975
  field_order = (
@@ -2943,13 +2978,14 @@ class PowerPortBulkCreateForm(
2943
2978
  "type",
2944
2979
  "maximum_draw",
2945
2980
  "allocated_draw",
2981
+ "power_factor",
2946
2982
  "description",
2947
2983
  "tags",
2948
2984
  )
2949
2985
 
2950
2986
 
2951
2987
  class ModulePowerPortBulkCreateForm(
2952
- form_from_model(PowerPort, ["type", "maximum_draw", "allocated_draw", "tags"]),
2988
+ form_from_model(PowerPort, ["type", "maximum_draw", "allocated_draw", "power_factor", "tags"]),
2953
2989
  ModuleBulkAddComponentForm,
2954
2990
  ):
2955
2991
  field_order = (
@@ -2958,13 +2994,14 @@ class ModulePowerPortBulkCreateForm(
2958
2994
  "type",
2959
2995
  "maximum_draw",
2960
2996
  "allocated_draw",
2997
+ "power_factor",
2961
2998
  "description",
2962
2999
  "tags",
2963
3000
  )
2964
3001
 
2965
3002
 
2966
3003
  class PowerPortBulkEditForm(
2967
- form_from_model(PowerPort, ["label", "type", "maximum_draw", "allocated_draw", "description"]),
3004
+ form_from_model(PowerPort, ["label", "type", "maximum_draw", "allocated_draw", "power_factor", "description"]),
2968
3005
  TagsBulkEditFormMixin,
2969
3006
  NautobotBulkEditForm,
2970
3007
  ):
@@ -4638,8 +4675,15 @@ class PowerPanelForm(LocatableModelFormMixin, NautobotModelForm):
4638
4675
  "location",
4639
4676
  "rack_group",
4640
4677
  "name",
4678
+ "panel_type",
4679
+ "breaker_position_count",
4680
+ "power_path",
4641
4681
  "tags",
4642
4682
  ]
4683
+ widgets = {
4684
+ "panel_type": StaticSelect2(),
4685
+ "power_path": StaticSelect2(),
4686
+ }
4643
4687
 
4644
4688
 
4645
4689
  class PowerPanelBulkEditForm(
@@ -4653,6 +4697,18 @@ class PowerPanelBulkEditForm(
4653
4697
  required=False,
4654
4698
  query_params={"location": "$location"},
4655
4699
  )
4700
+ panel_type = forms.ChoiceField(
4701
+ choices=add_blank_choice(PowerPanelTypeChoices),
4702
+ required=False,
4703
+ widget=StaticSelect2(),
4704
+ )
4705
+ breaker_position_count = forms.IntegerField(required=False, min_value=1)
4706
+ power_path = forms.ChoiceField(
4707
+ choices=add_blank_choice(PowerPathChoices),
4708
+ required=False,
4709
+ initial="",
4710
+ widget=StaticSelect2(),
4711
+ )
4656
4712
 
4657
4713
  class Meta:
4658
4714
  model = PowerPanel
@@ -4669,6 +4725,18 @@ class PowerPanelFilterForm(NautobotFilterForm, LocatableModelFilterFormMixin):
4669
4725
  null_option="None",
4670
4726
  query_params={"location": "$location"},
4671
4727
  )
4728
+ panel_type = forms.MultipleChoiceField(
4729
+ choices=add_blank_choice(PowerPanelTypeChoices),
4730
+ required=False,
4731
+ widget=StaticSelect2Multiple(),
4732
+ )
4733
+ breaker_position_count = forms.IntegerField(required=False, min_value=1)
4734
+ power_path = forms.ChoiceField(
4735
+ choices=add_blank_choice(PowerPathChoices),
4736
+ required=False,
4737
+ initial="",
4738
+ widget=StaticSelect2(),
4739
+ )
4672
4740
  tags = TagFilterField(model)
4673
4741
 
4674
4742
 
@@ -4683,41 +4751,56 @@ class PowerFeedForm(NautobotModelForm):
4683
4751
  required=False,
4684
4752
  initial_params={"power_panels": "$power_panel"},
4685
4753
  )
4686
- power_panel = DynamicModelChoiceField(queryset=PowerPanel.objects.all(), query_params={"location": "$location"})
4754
+ power_panel = DynamicModelChoiceField(
4755
+ queryset=PowerPanel.objects.all(),
4756
+ query_params={"location": "$location"},
4757
+ )
4758
+ destination_panel = DynamicModelChoiceField(
4759
+ queryset=PowerPanel.objects.all(),
4760
+ required=False,
4761
+ query_params={"location": "$location"},
4762
+ )
4687
4763
  rack = DynamicModelChoiceField(
4688
4764
  queryset=Rack.objects.all(),
4689
4765
  required=False,
4690
4766
  query_params={"location": "$location"},
4691
4767
  )
4692
- comments = CommentField()
4768
+ comments = CommentField(label="Comments")
4693
4769
 
4694
4770
  class Meta:
4695
4771
  model = PowerFeed
4696
4772
  fields = [
4697
4773
  "location",
4698
4774
  "power_panel",
4775
+ "destination_panel",
4699
4776
  "rack",
4700
4777
  "name",
4701
4778
  "status",
4702
4779
  "type",
4780
+ "power_path",
4703
4781
  "supply",
4704
4782
  "phase",
4705
4783
  "voltage",
4706
4784
  "amperage",
4707
4785
  "max_utilization",
4786
+ "breaker_position",
4787
+ "breaker_pole_count",
4708
4788
  "comments",
4709
4789
  "tags",
4710
4790
  ]
4711
4791
  widgets = {
4712
4792
  "type": StaticSelect2(),
4793
+ "power_path": StaticSelect2(),
4713
4794
  "supply": StaticSelect2(),
4714
4795
  "phase": StaticSelect2(),
4796
+ "breaker_pole_count": StaticSelect2(),
4715
4797
  }
4716
4798
 
4717
4799
 
4718
4800
  class PowerFeedBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFormMixin, NautobotBulkEditForm):
4719
4801
  pk = forms.ModelMultipleChoiceField(queryset=PowerFeed.objects.all(), widget=forms.MultipleHiddenInput)
4720
4802
  power_panel = DynamicModelChoiceField(queryset=PowerPanel.objects.all(), required=False)
4803
+ destination_panel = DynamicModelChoiceField(queryset=PowerPanel.objects.all(), required=False)
4721
4804
  rack = DynamicModelChoiceField(queryset=Rack.objects.all(), required=False)
4722
4805
  type = forms.ChoiceField(
4723
4806
  choices=add_blank_choice(PowerFeedTypeChoices),
@@ -4725,6 +4808,12 @@ class PowerFeedBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFormMixin,
4725
4808
  initial="",
4726
4809
  widget=StaticSelect2(),
4727
4810
  )
4811
+ power_path = forms.ChoiceField(
4812
+ choices=add_blank_choice(PowerPathChoices),
4813
+ required=False,
4814
+ initial="",
4815
+ widget=StaticSelect2(),
4816
+ )
4728
4817
  supply = forms.ChoiceField(
4729
4818
  choices=add_blank_choice(PowerFeedSupplyChoices),
4730
4819
  required=False,
@@ -4740,6 +4829,12 @@ class PowerFeedBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFormMixin,
4740
4829
  voltage = forms.IntegerField(required=False)
4741
4830
  amperage = forms.IntegerField(required=False)
4742
4831
  max_utilization = forms.IntegerField(required=False)
4832
+ breaker_position = forms.IntegerField(required=False, min_value=1)
4833
+ breaker_pole_count = forms.ChoiceField(
4834
+ choices=add_blank_choice(PowerFeedBreakerPoleChoices),
4835
+ required=False,
4836
+ widget=StaticSelect2(),
4837
+ )
4743
4838
  comments = CommentField(widget=SmallTextarea, label="Comments")
4744
4839
 
4745
4840
  class Meta:
@@ -4748,10 +4843,9 @@ class PowerFeedBulkEditForm(TagsBulkEditFormMixin, StatusModelBulkEditFormMixin,
4748
4843
  ]
4749
4844
 
4750
4845
 
4751
- class PowerFeedFilterForm(NautobotFilterForm, StatusModelFilterFormMixin):
4846
+ class PowerFeedFilterForm(NautobotFilterForm, StatusModelFilterFormMixin, LocatableModelFilterFormMixin):
4752
4847
  model = PowerFeed
4753
4848
  q = forms.CharField(required=False, label="Search")
4754
- location = DynamicModelMultipleChoiceField(queryset=Location.objects.all(), to_field_name="name", required=False)
4755
4849
  power_panel = DynamicModelMultipleChoiceField(
4756
4850
  queryset=PowerPanel.objects.all(),
4757
4851
  required=False,
@@ -4759,6 +4853,13 @@ class PowerFeedFilterForm(NautobotFilterForm, StatusModelFilterFormMixin):
4759
4853
  null_option="None",
4760
4854
  query_params={"location": "$location"},
4761
4855
  )
4856
+ destination_panel = DynamicModelMultipleChoiceField(
4857
+ queryset=PowerPanel.objects.all(),
4858
+ required=False,
4859
+ label="Destination panel",
4860
+ null_option="None",
4861
+ query_params={"location": "$location"},
4862
+ )
4762
4863
  rack = DynamicModelMultipleChoiceField(
4763
4864
  queryset=Rack.objects.all(),
4764
4865
  required=False,
@@ -4771,6 +4872,12 @@ class PowerFeedFilterForm(NautobotFilterForm, StatusModelFilterFormMixin):
4771
4872
  required=False,
4772
4873
  widget=StaticSelect2(),
4773
4874
  )
4875
+ power_path = forms.ChoiceField(
4876
+ choices=add_blank_choice(PowerPathChoices),
4877
+ required=False,
4878
+ initial="",
4879
+ widget=StaticSelect2(),
4880
+ )
4774
4881
  supply = forms.ChoiceField(
4775
4882
  choices=add_blank_choice(PowerFeedSupplyChoices),
4776
4883
  required=False,
@@ -4784,6 +4891,12 @@ class PowerFeedFilterForm(NautobotFilterForm, StatusModelFilterFormMixin):
4784
4891
  voltage = forms.IntegerField(required=False)
4785
4892
  amperage = forms.IntegerField(required=False)
4786
4893
  max_utilization = forms.IntegerField(required=False)
4894
+ breaker_position = forms.IntegerField(required=False, min_value=1)
4895
+ breaker_pole_count = forms.ChoiceField(
4896
+ choices=add_blank_choice(PowerFeedBreakerPoleChoices),
4897
+ required=False,
4898
+ widget=StaticSelect2(),
4899
+ )
4787
4900
  tags = TagFilterField(model)
4788
4901
 
4789
4902
 
@@ -47,7 +47,7 @@ class Command(BaseCommand):
47
47
  Draw a simple progress bar 20 increments wide illustrating the specified percentage.
48
48
  """
49
49
  bar_size = int(percentage / 5)
50
- self.stdout.write(f"\r [{'#' * bar_size}{' ' * (20-bar_size)}] {int(percentage)}%", ending="")
50
+ self.stdout.write(f"\r [{'#' * bar_size}{' ' * (20 - bar_size)}] {int(percentage)}%", ending="")
51
51
 
52
52
  def handle(self, *model_names, **options):
53
53
  # If --force was passed, first delete all existing CablePaths
@@ -0,0 +1,97 @@
1
+ # Generated by Django 4.2.23 on 2025-08-11 21:07
2
+
3
+ import django.core.validators
4
+ from django.db import migrations, models
5
+ import django.db.models.deletion
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+ dependencies = [
10
+ ("dcim", "0071_alter_consoleport_options_and_more"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterModelOptions(
15
+ name="powerfeed",
16
+ options={"ordering": ["power_panel", "breaker_position", "name"]},
17
+ ),
18
+ migrations.AlterUniqueTogether(
19
+ name="powerfeed",
20
+ unique_together={("power_panel", "name")},
21
+ ),
22
+ migrations.AddField(
23
+ model_name="powerfeed",
24
+ name="breaker_pole_count",
25
+ field=models.PositiveSmallIntegerField(blank=True, null=True),
26
+ ),
27
+ migrations.AddField(
28
+ model_name="powerfeed",
29
+ name="breaker_position",
30
+ field=models.PositiveIntegerField(blank=True, null=True),
31
+ ),
32
+ migrations.AddField(
33
+ model_name="powerfeed",
34
+ name="destination_panel",
35
+ field=models.ForeignKey(
36
+ blank=True,
37
+ null=True,
38
+ on_delete=django.db.models.deletion.PROTECT,
39
+ related_name="feeders",
40
+ to="dcim.powerpanel",
41
+ ),
42
+ ),
43
+ migrations.AddField(
44
+ model_name="powerfeed",
45
+ name="power_path",
46
+ field=models.CharField(blank=True, max_length=20),
47
+ ),
48
+ migrations.AddField(
49
+ model_name="powerpanel",
50
+ name="breaker_position_count",
51
+ field=models.PositiveIntegerField(blank=True, null=True),
52
+ ),
53
+ migrations.AddField(
54
+ model_name="powerpanel",
55
+ name="panel_type",
56
+ field=models.CharField(blank=True, max_length=30),
57
+ ),
58
+ migrations.AddField(
59
+ model_name="powerpanel",
60
+ name="power_path",
61
+ field=models.CharField(blank=True, max_length=20),
62
+ ),
63
+ migrations.AddField(
64
+ model_name="powerport",
65
+ name="power_factor",
66
+ field=models.DecimalField(
67
+ decimal_places=2,
68
+ default="0.95",
69
+ max_digits=4,
70
+ validators=[
71
+ django.core.validators.MinValueValidator(0.01),
72
+ django.core.validators.MaxValueValidator(1.0),
73
+ ],
74
+ ),
75
+ ),
76
+ migrations.AddField(
77
+ model_name="powerporttemplate",
78
+ name="power_factor",
79
+ field=models.DecimalField(
80
+ decimal_places=2,
81
+ default="0.95",
82
+ max_digits=4,
83
+ validators=[
84
+ django.core.validators.MinValueValidator(0.01),
85
+ django.core.validators.MaxValueValidator(1.0),
86
+ ],
87
+ ),
88
+ ),
89
+ migrations.AlterUniqueTogether(
90
+ name="powerfeed",
91
+ unique_together={("power_panel", "breaker_position"), ("power_panel", "name")},
92
+ ),
93
+ migrations.AddIndex(
94
+ model_name="powerfeed",
95
+ index=models.Index(fields=["power_panel", "breaker_position"], name="dcim_powerf_power_p_b4d96d_idx"),
96
+ ),
97
+ ]
@@ -249,6 +249,13 @@ class PowerPortTemplate(ModularComponentTemplateModel):
249
249
  validators=[MinValueValidator(1)],
250
250
  help_text="Allocated power draw (watts)",
251
251
  )
252
+ power_factor = models.DecimalField(
253
+ max_digits=4,
254
+ decimal_places=2,
255
+ default="0.95",
256
+ validators=[MinValueValidator(0.01), MaxValueValidator(1.00)],
257
+ help_text="Power factor (0.01-1.00) for converting between watts (W) and volt-amps (VA). Defaults to 0.95.",
258
+ )
252
259
 
253
260
  def instantiate(self, device, module=None):
254
261
  return self.instantiate_model(
@@ -258,6 +265,7 @@ class PowerPortTemplate(ModularComponentTemplateModel):
258
265
  type=self.type,
259
266
  maximum_draw=self.maximum_draw,
260
267
  allocated_draw=self.allocated_draw,
268
+ power_factor=self.power_factor,
261
269
  )
262
270
 
263
271
  def clean(self):
@@ -36,6 +36,7 @@ from nautobot.dcim.constants import (
36
36
  VIRTUAL_IFACE_TYPES,
37
37
  WIRELESS_IFACE_TYPES,
38
38
  )
39
+ from nautobot.dcim.utils import convert_watts_to_va
39
40
  from nautobot.extras.models import (
40
41
  ChangeLoggedModel,
41
42
  RelationshipModel,
@@ -398,6 +399,13 @@ class PowerPort(ModularComponentModel, CableTermination, PathEndpoint):
398
399
  validators=[MinValueValidator(1)],
399
400
  help_text="Allocated power draw (watts)",
400
401
  )
402
+ power_factor = models.DecimalField(
403
+ max_digits=4,
404
+ decimal_places=2,
405
+ default="0.95",
406
+ validators=[MinValueValidator(0.01), MaxValueValidator(1.00)],
407
+ help_text="Power factor (0.01-1.00) for converting between watts (W) and volt-amps (VA). Defaults to 0.95.",
408
+ )
401
409
 
402
410
  def clean(self):
403
411
  super().clean()
@@ -422,16 +430,19 @@ class PowerPort(ModularComponentModel, CableTermination, PathEndpoint):
422
430
  maximum_draw_total=Sum("maximum_draw"),
423
431
  allocated_draw_total=Sum("allocated_draw"),
424
432
  )
425
- numerator = utilization["allocated_draw_total"] or 0
426
- denominator = utilization["maximum_draw_total"] or 0
433
+
434
+ # Convert watts to VA for aggregated values
435
+ allocated_va = convert_watts_to_va(utilization["allocated_draw_total"], self.power_factor)
436
+ maximum_va = convert_watts_to_va(utilization["maximum_draw_total"], self.power_factor)
437
+
427
438
  ret = {
428
- "allocated": utilization["allocated_draw_total"] or 0,
429
- "maximum": utilization["maximum_draw_total"] or 0,
439
+ "allocated": allocated_va,
440
+ "maximum": maximum_va,
430
441
  "outlet_count": len(outlet_ids),
431
442
  "legs": [],
432
443
  "utilization_data": UtilizationData(
433
- numerator=numerator,
434
- denominator=denominator,
444
+ numerator=allocated_va,
445
+ denominator=maximum_va,
435
446
  ),
436
447
  }
437
448
 
@@ -446,11 +457,16 @@ class PowerPort(ModularComponentModel, CableTermination, PathEndpoint):
446
457
  maximum_draw_total=Sum("maximum_draw"),
447
458
  allocated_draw_total=Sum("allocated_draw"),
448
459
  )
460
+
461
+ # Convert watts to VA for leg values
462
+ leg_allocated_va = convert_watts_to_va(utilization["allocated_draw_total"], self.power_factor)
463
+ leg_maximum_va = convert_watts_to_va(utilization["maximum_draw_total"], self.power_factor)
464
+
449
465
  ret["legs"].append(
450
466
  {
451
467
  "name": leg_name,
452
- "allocated": utilization["allocated_draw_total"] or 0,
453
- "maximum": utilization["maximum_draw_total"] or 0,
468
+ "allocated": leg_allocated_va,
469
+ "maximum": leg_maximum_va,
454
470
  "outlet_count": len(outlet_ids),
455
471
  }
456
472
  )
@@ -462,13 +478,16 @@ class PowerPort(ModularComponentModel, CableTermination, PathEndpoint):
462
478
  else:
463
479
  denominator = 0
464
480
 
465
- # Default to administratively defined values
481
+ # Convert administratively defined values from watts to VA
482
+ allocated_va = convert_watts_to_va(self.allocated_draw, self.power_factor)
483
+ maximum_va = convert_watts_to_va(self.maximum_draw, self.power_factor)
484
+
466
485
  return {
467
- "allocated": self.allocated_draw or 0,
468
- "maximum": self.maximum_draw or 0,
486
+ "allocated": allocated_va,
487
+ "maximum": maximum_va,
469
488
  "outlet_count": PowerOutlet.objects.filter(power_port=self).count(),
470
489
  "legs": [],
471
- "utilization_data": UtilizationData(numerator=self.allocated_draw or 0, denominator=denominator),
490
+ "utilization_data": UtilizationData(numerator=allocated_va, denominator=denominator),
472
491
  }
473
492
 
474
493
 
@@ -829,7 +829,7 @@ class Device(PrimaryModel, ConfigContextModel):
829
829
  if existing_virtual_chassis and existing_virtual_chassis.master == self:
830
830
  raise ValidationError(
831
831
  {
832
- "virtual_chassis": f"The master device for the virtual chassis ({ existing_virtual_chassis}) may not be removed"
832
+ "virtual_chassis": f"The master device for the virtual chassis ({existing_virtual_chassis}) may not be removed"
833
833
  }
834
834
  )
835
835