nautobot 2.2.9__py3-none-any.whl → 2.3.0b1__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (697) hide show
  1. nautobot/apps/forms.py +4 -0
  2. nautobot/apps/models.py +10 -1
  3. nautobot/circuits/__init__.py +0 -1
  4. nautobot/circuits/apps.py +1 -0
  5. nautobot/circuits/factory.py +15 -3
  6. nautobot/circuits/filters.py +13 -0
  7. nautobot/circuits/forms.py +13 -0
  8. nautobot/circuits/migrations/0021_alter_circuit_status_alter_circuittermination__path.py +32 -0
  9. nautobot/circuits/migrations/0022_circuittermination_cloud_network.py +25 -0
  10. nautobot/circuits/models.py +16 -3
  11. nautobot/circuits/tables.py +16 -2
  12. nautobot/circuits/templates/circuits/circuittermination_create.html +10 -2
  13. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +6 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -1
  15. nautobot/circuits/tests/test_api.py +7 -5
  16. nautobot/circuits/tests/test_filters.py +12 -5
  17. nautobot/circuits/tests/test_models.py +33 -2
  18. nautobot/circuits/views.py +2 -3
  19. nautobot/cloud/__init__.py +0 -0
  20. nautobot/cloud/api/__init__.py +0 -0
  21. nautobot/cloud/api/serializers.py +54 -0
  22. nautobot/cloud/api/urls.py +16 -0
  23. nautobot/cloud/api/views.py +48 -0
  24. nautobot/cloud/apps.py +13 -0
  25. nautobot/cloud/factory.py +111 -0
  26. nautobot/cloud/filters.py +184 -0
  27. nautobot/cloud/forms.py +333 -0
  28. nautobot/cloud/homepage.py +43 -0
  29. nautobot/cloud/migrations/0001_initial.py +304 -0
  30. nautobot/cloud/migrations/__init__.py +0 -0
  31. nautobot/cloud/models.py +247 -0
  32. nautobot/cloud/navigation.py +85 -0
  33. nautobot/cloud/tables.py +173 -0
  34. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +43 -0
  35. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +128 -0
  36. nautobot/cloud/templates/cloud/cloudnetwork_update.html +33 -0
  37. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +100 -0
  38. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +65 -0
  39. nautobot/cloud/templates/cloud/cloudservice_update.html +25 -0
  40. nautobot/cloud/tests/__init__.py +0 -0
  41. nautobot/cloud/tests/test_api.py +248 -0
  42. nautobot/cloud/tests/test_filters.py +113 -0
  43. nautobot/cloud/tests/test_models.py +43 -0
  44. nautobot/cloud/tests/test_views.py +153 -0
  45. nautobot/cloud/urls.py +14 -0
  46. nautobot/cloud/views.py +181 -0
  47. nautobot/core/__init__.py +0 -3
  48. nautobot/core/api/metadata.py +1 -0
  49. nautobot/core/api/parsers.py +7 -1
  50. nautobot/core/api/urls.py +1 -0
  51. nautobot/core/api/utils.py +1 -0
  52. nautobot/core/api/views.py +4 -0
  53. nautobot/core/apps/__init__.py +6 -3
  54. nautobot/core/constants.py +8 -0
  55. nautobot/core/factory.py +32 -1
  56. nautobot/core/filters.py +96 -28
  57. nautobot/core/forms/fields.py +10 -4
  58. nautobot/core/forms/forms.py +1 -1
  59. nautobot/core/forms/widgets.py +18 -1
  60. nautobot/core/graphql/generators.py +2 -2
  61. nautobot/core/graphql/schema.py +34 -4
  62. nautobot/core/jobs/__init__.py +17 -6
  63. nautobot/core/jobs/cleanup.py +100 -0
  64. nautobot/core/jobs/groups.py +38 -0
  65. nautobot/core/management/commands/generate_test_data.py +116 -3
  66. nautobot/core/models/__init__.py +34 -9
  67. nautobot/core/models/generics.py +19 -3
  68. nautobot/core/models/name_color_content_types.py +7 -28
  69. nautobot/core/models/querysets.py +4 -3
  70. nautobot/core/models/tree_queries.py +1 -1
  71. nautobot/core/models/utils.py +21 -5
  72. nautobot/core/settings.py +4 -30
  73. nautobot/core/settings.yaml +34 -27
  74. nautobot/core/settings_funcs.py +103 -0
  75. nautobot/core/tables.py +127 -56
  76. nautobot/core/templates/admin/search_form.html +1 -1
  77. nautobot/core/templates/buttons/add.html +11 -3
  78. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +13 -0
  79. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +13 -0
  80. nautobot/core/templates/buttons/export.html +101 -53
  81. nautobot/core/templates/buttons/job_import.html +11 -3
  82. nautobot/core/templates/generic/object_bulk_destroy.html +3 -1
  83. nautobot/core/templates/generic/object_bulk_update.html +3 -1
  84. nautobot/core/templates/generic/object_changelog.html +0 -9
  85. nautobot/core/templates/generic/object_list.html +156 -17
  86. nautobot/core/templates/generic/object_retrieve.html +80 -16
  87. nautobot/core/templates/inc/extras_features_edit_form_fields.html +8 -0
  88. nautobot/core/templates/inc/javascript.html +2 -0
  89. nautobot/core/templates/inc/media.html +2 -2
  90. nautobot/core/templates/inc/nav_menu.html +1 -0
  91. nautobot/core/templates/inc/paginator.html +7 -7
  92. nautobot/core/templates/inc/search_panel.html +2 -2
  93. nautobot/core/templates/inc/table.html +2 -2
  94. nautobot/core/templates/nautobot_config.py.j2 +13 -23
  95. nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +37 -0
  96. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +2 -2
  97. nautobot/core/templates/utilities/templatetags/saved_view_modal.html +38 -0
  98. nautobot/core/templates/utilities/theme_preview.html +25 -8
  99. nautobot/core/templates/utilities/worker_status.html +152 -0
  100. nautobot/core/templatetags/buttons.py +335 -38
  101. nautobot/core/templatetags/form_helpers.py +1 -1
  102. nautobot/core/templatetags/helpers.py +181 -11
  103. nautobot/core/testing/api.py +5 -4
  104. nautobot/core/testing/filters.py +51 -13
  105. nautobot/core/testing/mixins.py +46 -0
  106. nautobot/core/testing/models.py +22 -0
  107. nautobot/core/testing/schema.py +4 -8
  108. nautobot/core/testing/views.py +31 -14
  109. nautobot/core/tests/integration/test_general_functionality.py +1 -1
  110. nautobot/core/tests/integration/test_import_objects_ui.py +1 -0
  111. nautobot/core/tests/integration/test_swagger.py +1 -1
  112. nautobot/core/tests/nautobot_config.py +0 -1
  113. nautobot/core/tests/runner.py +2 -2
  114. nautobot/core/tests/test_api.py +1 -0
  115. nautobot/core/tests/test_authentication.py +7 -2
  116. nautobot/core/tests/test_filters.py +11 -9
  117. nautobot/core/tests/test_forms.py +9 -0
  118. nautobot/core/tests/test_graphql.py +27 -16
  119. nautobot/core/tests/test_jobs.py +123 -74
  120. nautobot/core/tests/test_tables.py +3 -1
  121. nautobot/core/tests/test_templatetags_helpers.py +12 -5
  122. nautobot/core/tests/test_utils.py +31 -20
  123. nautobot/core/tests/test_views.py +6 -6
  124. nautobot/core/urls.py +8 -3
  125. nautobot/core/utils/deprecation.py +29 -0
  126. nautobot/core/utils/filtering.py +12 -9
  127. nautobot/core/utils/lookup.py +37 -2
  128. nautobot/core/utils/requests.py +4 -1
  129. nautobot/core/views/__init__.py +137 -24
  130. nautobot/core/views/generic.py +118 -66
  131. nautobot/core/views/mixins.py +104 -35
  132. nautobot/core/views/paginator.py +9 -3
  133. nautobot/core/views/renderers.py +121 -56
  134. nautobot/core/views/utils.py +79 -1
  135. nautobot/dcim/__init__.py +0 -1
  136. nautobot/dcim/api/serializers.py +180 -44
  137. nautobot/dcim/api/urls.py +7 -3
  138. nautobot/dcim/api/views.py +53 -7
  139. nautobot/dcim/apps.py +3 -0
  140. nautobot/dcim/choices.py +25 -0
  141. nautobot/dcim/constants.py +7 -0
  142. nautobot/dcim/factory.py +249 -18
  143. nautobot/dcim/filters/__init__.py +369 -193
  144. nautobot/dcim/filters/mixins.py +274 -1
  145. nautobot/dcim/forms.py +817 -109
  146. nautobot/dcim/graphql/types.py +2 -2
  147. nautobot/dcim/homepage.py +1 -1
  148. nautobot/dcim/migrations/0059_add_role_field_to_interface_models.py +27 -0
  149. nautobot/dcim/migrations/0060_alter_cable_status_alter_consoleport__path_and_more.py +303 -0
  150. nautobot/dcim/migrations/0061_module_models.py +861 -0
  151. nautobot/dcim/migrations/0062_module_data_migration.py +25 -0
  152. nautobot/dcim/models/__init__.py +8 -0
  153. nautobot/dcim/models/cables.py +15 -0
  154. nautobot/dcim/models/device_component_templates.py +207 -53
  155. nautobot/dcim/models/device_components.py +275 -106
  156. nautobot/dcim/models/devices.py +466 -13
  157. nautobot/dcim/navigation.py +47 -0
  158. nautobot/dcim/signals.py +3 -3
  159. nautobot/dcim/tables/__init__.py +35 -23
  160. nautobot/dcim/tables/devices.py +231 -59
  161. nautobot/dcim/tables/devicetypes.py +65 -9
  162. nautobot/dcim/tables/racks.py +5 -1
  163. nautobot/dcim/tables/template_code.py +46 -26
  164. nautobot/dcim/templates/dcim/cable_connect.html +76 -3
  165. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -5
  166. nautobot/dcim/templates/dcim/device/base.html +15 -7
  167. nautobot/dcim/templates/dcim/device/consoleports.html +2 -3
  168. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -3
  169. nautobot/dcim/templates/dcim/device/devicebays.html +6 -7
  170. nautobot/dcim/templates/dcim/device/frontports.html +2 -3
  171. nautobot/dcim/templates/dcim/device/interfaces.html +2 -3
  172. nautobot/dcim/templates/dcim/device/inventory.html +2 -3
  173. nautobot/dcim/templates/dcim/device/modulebays.html +49 -0
  174. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -3
  175. nautobot/dcim/templates/dcim/device/powerports.html +2 -3
  176. nautobot/dcim/templates/dcim/device/rearports.html +2 -3
  177. nautobot/dcim/templates/dcim/device.html +45 -1
  178. nautobot/dcim/templates/dcim/device_component.html +13 -5
  179. nautobot/dcim/templates/dcim/device_list.html +2 -1
  180. nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +0 -6
  181. nautobot/dcim/templates/dcim/devicetype.html +99 -98
  182. nautobot/dcim/templates/dcim/devicetype_list.html +8 -16
  183. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  184. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +39 -0
  185. nautobot/dcim/templates/dcim/interface.html +17 -2
  186. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -5
  187. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  188. nautobot/dcim/templates/dcim/manufacturer.html +24 -0
  189. nautobot/dcim/templates/dcim/module/base.html +97 -0
  190. nautobot/dcim/templates/dcim/module_bulk_destroy.html +5 -0
  191. nautobot/dcim/templates/dcim/module_consoleports.html +53 -0
  192. nautobot/dcim/templates/dcim/module_consoleserverports.html +53 -0
  193. nautobot/dcim/templates/dcim/module_destroy.html +5 -0
  194. nautobot/dcim/templates/dcim/module_frontports.html +53 -0
  195. nautobot/dcim/templates/dcim/module_interfaces.html +57 -0
  196. nautobot/dcim/templates/dcim/module_list.html +20 -0
  197. nautobot/dcim/templates/dcim/module_modulebays.html +49 -0
  198. nautobot/dcim/templates/dcim/module_poweroutlets.html +53 -0
  199. nautobot/dcim/templates/dcim/module_powerports.html +53 -0
  200. nautobot/dcim/templates/dcim/module_rearports.html +53 -0
  201. nautobot/dcim/templates/dcim/module_retrieve.html +63 -0
  202. nautobot/dcim/templates/dcim/module_update.html +71 -0
  203. nautobot/dcim/templates/dcim/modulebay_bulk_destroy.html +5 -0
  204. nautobot/dcim/templates/dcim/modulebay_destroy.html +8 -0
  205. nautobot/dcim/templates/dcim/modulebay_retrieve.html +101 -0
  206. nautobot/dcim/templates/dcim/moduletype_list.html +11 -0
  207. nautobot/dcim/templates/dcim/moduletype_retrieve.html +142 -0
  208. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -5
  209. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +65 -19
  210. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  211. nautobot/dcim/tests/test_api.py +691 -208
  212. nautobot/dcim/tests/test_filters.py +836 -217
  213. nautobot/dcim/tests/test_models.py +1072 -39
  214. nautobot/dcim/tests/test_views.py +1488 -358
  215. nautobot/dcim/urls.py +17 -2
  216. nautobot/dcim/utils.py +2 -3
  217. nautobot/dcim/views.py +1107 -120
  218. nautobot/extras/__init__.py +0 -1
  219. nautobot/extras/api/serializers.py +115 -3
  220. nautobot/extras/api/urls.py +12 -0
  221. nautobot/extras/api/views.py +125 -7
  222. nautobot/extras/apps.py +2 -2
  223. nautobot/extras/choices.py +43 -0
  224. nautobot/extras/context_managers.py +13 -8
  225. nautobot/extras/datasources/git.py +2 -0
  226. nautobot/extras/factory.py +422 -9
  227. nautobot/extras/filters/__init__.py +174 -3
  228. nautobot/extras/filters/mixins.py +46 -43
  229. nautobot/extras/forms/base.py +17 -4
  230. nautobot/extras/forms/forms.py +227 -8
  231. nautobot/extras/forms/mixins.py +93 -0
  232. nautobot/extras/graphql/types.py +23 -10
  233. nautobot/extras/homepage.py +16 -13
  234. nautobot/extras/jobs.py +2 -2
  235. nautobot/extras/management/__init__.py +1 -0
  236. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -16
  237. nautobot/extras/migrations/0021_customfield_changelog_data.py +1 -0
  238. nautobot/extras/migrations/0109_dynamicgroup_group_type_dynamicgroup_tags_and_more.py +108 -0
  239. nautobot/extras/migrations/0110_alter_configcontext_cluster_groups_and_more.py +111 -0
  240. nautobot/extras/migrations/0111_metadata.py +162 -0
  241. nautobot/extras/migrations/0112_dynamic_group_group_type_data_migration.py +28 -0
  242. nautobot/extras/migrations/0113_saved_views.py +77 -0
  243. nautobot/extras/models/__init__.py +15 -1
  244. nautobot/extras/models/change_logging.py +3 -3
  245. nautobot/extras/models/contacts.py +4 -0
  246. nautobot/extras/models/customfields.py +18 -3
  247. nautobot/extras/models/groups.py +389 -225
  248. nautobot/extras/models/jobs.py +4 -84
  249. nautobot/extras/models/metadata.py +441 -0
  250. nautobot/extras/models/mixins.py +72 -62
  251. nautobot/extras/models/models.py +116 -9
  252. nautobot/extras/models/relationships.py +9 -2
  253. nautobot/extras/models/tags.py +13 -2
  254. nautobot/extras/navigation.py +57 -0
  255. nautobot/extras/plugins/__init__.py +3 -1
  256. nautobot/extras/querysets.py +30 -66
  257. nautobot/extras/signals.py +96 -114
  258. nautobot/extras/tables.py +171 -47
  259. nautobot/extras/templates/extras/dynamicgroup.html +44 -15
  260. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -0
  261. nautobot/extras/templates/extras/job.html +1 -1
  262. nautobot/extras/templates/extras/job_detail.html +0 -11
  263. nautobot/extras/templates/extras/jobresult.html +61 -74
  264. nautobot/extras/templates/extras/metadatatype_create.html +89 -0
  265. nautobot/extras/templates/extras/metadatatype_retrieve.html +67 -0
  266. nautobot/extras/templates/extras/object_dynamicgroups.html +7 -0
  267. nautobot/extras/templates/extras/objectchange_list.html +0 -12
  268. nautobot/extras/templates/extras/plugins_list.html +1 -3
  269. nautobot/extras/templates/extras/role_retrieve.html +48 -0
  270. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +20 -0
  271. nautobot/extras/tests/integration/test_customfields.py +1 -0
  272. nautobot/extras/tests/test_api.py +501 -22
  273. nautobot/extras/tests/test_changelog.py +20 -9
  274. nautobot/extras/tests/test_context_managers.py +22 -15
  275. nautobot/extras/tests/test_datasources.py +13 -1
  276. nautobot/extras/tests/test_dynamicgroups.py +201 -171
  277. nautobot/extras/tests/test_filters.py +211 -12
  278. nautobot/extras/tests/test_jobs.py +4 -4
  279. nautobot/extras/tests/test_models.py +499 -4
  280. nautobot/extras/tests/test_relationships.py +1 -0
  281. nautobot/extras/tests/test_views.py +565 -28
  282. nautobot/extras/tests/test_webhooks.py +1 -1
  283. nautobot/extras/urls.py +5 -0
  284. nautobot/extras/utils.py +56 -45
  285. nautobot/extras/views.py +585 -96
  286. nautobot/ipam/__init__.py +0 -1
  287. nautobot/ipam/apps.py +1 -0
  288. nautobot/ipam/factory.py +17 -19
  289. nautobot/ipam/filters.py +14 -1
  290. nautobot/ipam/forms.py +9 -5
  291. nautobot/ipam/graphql/types.py +2 -2
  292. nautobot/ipam/migrations/0047_alter_ipaddress_role_alter_ipaddress_status_and_more.py +59 -0
  293. nautobot/ipam/models.py +23 -9
  294. nautobot/ipam/querysets.py +1 -1
  295. nautobot/ipam/signals.py +4 -2
  296. nautobot/ipam/tables.py +1 -0
  297. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +1 -1
  298. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +1 -1
  299. nautobot/ipam/templates/ipam/prefix.html +1 -0
  300. nautobot/ipam/tests/test_api.py +37 -18
  301. nautobot/ipam/tests/test_filters.py +26 -2
  302. nautobot/ipam/tests/test_models.py +8 -3
  303. nautobot/ipam/tests/test_querysets.py +1 -1
  304. nautobot/ipam/tests/test_views.py +3 -2
  305. nautobot/ipam/urls.py +2 -2
  306. nautobot/ipam/views.py +25 -28
  307. nautobot/project-static/css/base.css +20 -1
  308. nautobot/project-static/css/dark.css +11 -0
  309. nautobot/project-static/docs/404.html +884 -80
  310. nautobot/project-static/docs/apps/index.html +884 -80
  311. nautobot/project-static/docs/apps/nautobot-apps.html +884 -80
  312. nautobot/project-static/docs/assets/_mkdocstrings.css +5 -0
  313. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +911 -112
  314. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +896 -93
  315. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1457 -790
  316. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +927 -136
  317. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +969 -180
  318. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +893 -91
  319. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +889 -85
  320. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +983 -185
  321. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +938 -143
  322. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1064 -274
  323. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1190 -346
  324. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1663 -865
  325. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1156 -373
  326. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2200 -1502
  327. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2229 -1421
  328. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +904 -103
  329. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +955 -155
  330. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1002 -215
  331. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +1911 -1275
  332. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1835 -1091
  333. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +896 -93
  334. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2323 -1693
  335. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1785 -1023
  336. nautobot/project-static/docs/development/apps/api/configuration-view.html +884 -80
  337. nautobot/project-static/docs/development/apps/api/database-backend-config.html +884 -80
  338. nautobot/project-static/docs/development/apps/api/models/django-admin.html +884 -80
  339. nautobot/project-static/docs/development/apps/api/models/global-search.html +884 -80
  340. nautobot/project-static/docs/development/apps/api/models/graphql.html +884 -80
  341. nautobot/project-static/docs/development/apps/api/models/index.html +922 -81
  342. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +884 -80
  343. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +884 -80
  344. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +884 -80
  345. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +884 -80
  346. nautobot/project-static/docs/development/apps/api/platform-features/index.html +884 -80
  347. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +884 -80
  348. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +884 -80
  349. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +884 -80
  350. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +884 -80
  351. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +884 -80
  352. nautobot/project-static/docs/development/apps/api/prometheus.html +884 -80
  353. nautobot/project-static/docs/development/apps/api/setup.html +884 -80
  354. nautobot/project-static/docs/development/apps/api/testing.html +884 -80
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +884 -80
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +884 -80
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +884 -80
  358. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +884 -80
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +884 -80
  360. nautobot/project-static/docs/development/apps/api/views/base-template.html +884 -80
  361. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +884 -80
  362. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +884 -80
  363. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +884 -80
  364. nautobot/project-static/docs/development/apps/api/views/index.html +884 -80
  365. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +884 -80
  366. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +884 -80
  367. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +884 -80
  368. nautobot/project-static/docs/development/apps/api/views/notes.html +884 -80
  369. nautobot/project-static/docs/development/apps/api/views/rest-api.html +884 -80
  370. nautobot/project-static/docs/development/apps/api/views/urls.html +884 -80
  371. nautobot/project-static/docs/development/apps/index.html +884 -80
  372. nautobot/project-static/docs/development/apps/migration/code-updates.html +884 -80
  373. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +884 -80
  374. nautobot/project-static/docs/development/apps/migration/from-v1.html +884 -80
  375. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +884 -80
  376. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +884 -80
  377. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +884 -80
  378. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +884 -80
  379. nautobot/project-static/docs/development/apps/porting-from-netbox.html +884 -80
  380. nautobot/project-static/docs/development/core/application-registry.html +884 -80
  381. nautobot/project-static/docs/development/core/best-practices.html +885 -80
  382. nautobot/project-static/docs/development/core/bootstrap-ui.html +884 -80
  383. nautobot/project-static/docs/development/core/caching.html +884 -80
  384. nautobot/project-static/docs/development/core/controllers.html +884 -80
  385. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +884 -80
  386. nautobot/project-static/docs/development/core/generic-views.html +884 -80
  387. nautobot/project-static/docs/development/core/getting-started.html +884 -80
  388. nautobot/project-static/docs/development/core/homepage.html +884 -80
  389. nautobot/project-static/docs/development/core/index.html +884 -91
  390. nautobot/project-static/docs/development/core/model-checklist.html +887 -81
  391. nautobot/project-static/docs/development/core/model-features.html +884 -80
  392. nautobot/project-static/docs/development/core/natural-keys.html +884 -80
  393. nautobot/project-static/docs/development/core/navigation-menu.html +884 -80
  394. nautobot/project-static/docs/development/core/release-checklist.html +887 -83
  395. nautobot/project-static/docs/development/core/role-internals.html +884 -80
  396. nautobot/project-static/docs/development/core/settings.html +884 -80
  397. nautobot/project-static/docs/development/core/style-guide.html +885 -81
  398. nautobot/project-static/docs/development/core/templates.html +896 -81
  399. nautobot/project-static/docs/development/core/testing.html +884 -80
  400. nautobot/project-static/docs/development/core/user-preferences.html +884 -80
  401. nautobot/project-static/docs/development/index.html +884 -80
  402. nautobot/project-static/docs/development/jobs/index.html +1247 -457
  403. nautobot/project-static/docs/development/jobs/migration/from-v1.html +884 -80
  404. nautobot/project-static/docs/index.html +13 -8228
  405. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_dark.png +0 -0
  406. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_light.png +0 -0
  407. nautobot/project-static/docs/models/cloud/cloudaccount.html +15 -0
  408. nautobot/project-static/docs/models/cloud/cloudnetwork.html +15 -0
  409. nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +15 -0
  410. nautobot/project-static/docs/models/cloud/cloudresourcetype.html +15 -0
  411. nautobot/project-static/docs/models/cloud/cloudservice.html +15 -0
  412. nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +15 -0
  413. nautobot/project-static/docs/models/dcim/module.html +15 -0
  414. nautobot/project-static/docs/models/dcim/modulebay.html +15 -0
  415. nautobot/project-static/docs/models/dcim/modulebaytemplate.html +15 -0
  416. nautobot/project-static/docs/models/dcim/moduletype.html +15 -0
  417. nautobot/project-static/docs/models/extras/metadatachoice.html +15 -0
  418. nautobot/project-static/docs/models/extras/metadatatype.html +15 -0
  419. nautobot/project-static/docs/models/extras/objectmetadata.html +15 -0
  420. nautobot/project-static/docs/models/extras/role.html +15 -0
  421. nautobot/project-static/docs/models/extras/savedview.html +15 -0
  422. nautobot/project-static/docs/models/extras/staticgroupassociation.html +15 -0
  423. nautobot/project-static/docs/models/extras/status.html +15 -0
  424. nautobot/project-static/docs/objects.inv +0 -0
  425. nautobot/project-static/docs/overview/application_stack.html +892 -81
  426. nautobot/project-static/docs/overview/design_philosophy.html +886 -82
  427. nautobot/project-static/docs/overview/index.html +9032 -13
  428. nautobot/project-static/docs/release-notes/index.html +887 -83
  429. nautobot/project-static/docs/release-notes/version-1.0.html +884 -80
  430. nautobot/project-static/docs/release-notes/version-1.1.html +884 -80
  431. nautobot/project-static/docs/release-notes/version-1.2.html +884 -80
  432. nautobot/project-static/docs/release-notes/version-1.3.html +884 -80
  433. nautobot/project-static/docs/release-notes/version-1.4.html +884 -80
  434. nautobot/project-static/docs/release-notes/version-1.5.html +885 -81
  435. nautobot/project-static/docs/release-notes/version-1.6.html +885 -81
  436. nautobot/project-static/docs/release-notes/version-2.0.html +884 -80
  437. nautobot/project-static/docs/release-notes/version-2.1.html +884 -80
  438. nautobot/project-static/docs/release-notes/version-2.2.html +990 -323
  439. nautobot/project-static/docs/release-notes/version-2.3.html +9524 -0
  440. nautobot/project-static/docs/requirements.txt +4 -4
  441. nautobot/project-static/docs/search/search_index.json +1 -1
  442. nautobot/project-static/docs/sitemap.xml +335 -260
  443. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  444. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +884 -80
  445. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +884 -80
  446. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +884 -80
  447. nautobot/project-static/docs/user-guide/administration/configuration/index.html +884 -80
  448. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +983 -197
  449. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +884 -80
  450. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +884 -80
  451. nautobot/project-static/docs/user-guide/administration/guides/caching.html +884 -80
  452. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +888 -84
  453. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +884 -80
  454. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +884 -80
  455. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +884 -80
  456. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +884 -80
  457. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +884 -80
  458. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +884 -80
  459. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +884 -80
  460. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +884 -80
  461. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +884 -80
  462. nautobot/project-static/docs/user-guide/administration/installation/index.html +888 -80
  463. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +884 -80
  464. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +884 -80
  465. nautobot/project-static/docs/user-guide/administration/installation/services.html +888 -80
  466. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +900 -91
  467. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +884 -80
  468. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +884 -80
  469. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +884 -80
  470. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +884 -80
  471. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +915 -163
  472. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +884 -80
  473. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +884 -80
  474. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +884 -80
  475. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +884 -80
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +884 -80
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +884 -80
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +884 -80
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +884 -80
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +884 -80
  481. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +884 -80
  482. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +884 -80
  483. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +885 -81
  484. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +884 -80
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +888 -80
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +887 -83
  487. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +8984 -0
  488. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +8828 -0
  489. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +8829 -0
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +8828 -0
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +8829 -0
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +8833 -0
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +8828 -0
  494. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +898 -94
  495. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +915 -97
  496. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +915 -97
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +910 -92
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +915 -97
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +898 -94
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +898 -94
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +905 -97
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +912 -108
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +913 -109
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +910 -106
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +898 -94
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +906 -97
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +918 -100
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +928 -110
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +920 -98
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +898 -94
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +929 -111
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +920 -102
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +910 -106
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +913 -109
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +914 -106
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +8828 -0
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +8846 -0
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +8843 -0
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +8823 -0
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +908 -104
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +898 -94
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +932 -75
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +916 -98
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +898 -94
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +935 -78
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +913 -95
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +921 -117
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +910 -106
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +898 -94
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +914 -96
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +916 -98
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +898 -94
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +898 -94
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +898 -94
  535. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +884 -80
  536. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +884 -80
  537. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +889 -81
  538. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +889 -81
  539. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +884 -80
  540. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +884 -80
  541. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +884 -80
  542. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +884 -80
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +884 -80
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +884 -80
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +884 -80
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +884 -80
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +884 -80
  548. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +884 -80
  549. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +893 -88
  550. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +884 -80
  551. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +884 -80
  552. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +884 -80
  553. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +884 -80
  554. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +884 -80
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +889 -81
  556. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +884 -80
  557. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +884 -80
  558. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +884 -80
  559. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +884 -80
  560. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +884 -80
  561. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +884 -80
  562. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +884 -80
  563. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +884 -80
  564. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +884 -80
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +884 -80
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +884 -80
  567. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +884 -80
  568. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +884 -80
  569. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/clear-view-button.png +0 -0
  570. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/cleared-view.png +0 -0
  571. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/config-table-columns-to-locations.png +0 -0
  572. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/configure-button.png +0 -0
  573. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/create-saved-view-success.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/current-saved-view-drop-down-menu.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/default-location-list-view.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/dropdown-button-after-new-saved-view.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-application-to-locations.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-button.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/global-default-location-list-view.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/location-list-view-with-saved-views.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/navigation-menu.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-as-new-view-drop-down.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-view-modal.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-buttons.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-success.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view-unchecked.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-different-user.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-modal-unchecked.png +0 -0
  590. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-button.png +0 -0
  591. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-success.png +0 -0
  592. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/unsaved-saved-view.png +0 -0
  593. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/updated-saved-view.png +0 -0
  594. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +884 -80
  595. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +884 -80
  596. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +884 -80
  597. nautobot/project-static/docs/user-guide/index.html +884 -80
  598. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +884 -80
  599. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +884 -80
  600. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +884 -80
  601. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +884 -80
  602. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1250 -777
  603. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +887 -83
  604. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +884 -80
  605. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +884 -80
  606. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +884 -80
  607. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +884 -80
  608. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +884 -80
  609. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +884 -80
  610. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +887 -83
  611. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +884 -80
  612. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +884 -80
  613. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +888 -80
  614. nautobot/project-static/docs/user-guide/platform-functionality/metadata.html +8948 -0
  615. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +887 -83
  616. nautobot/project-static/docs/user-guide/platform-functionality/note.html +884 -80
  617. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +884 -80
  618. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +884 -80
  619. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +884 -80
  620. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +884 -80
  621. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +884 -80
  622. nautobot/project-static/docs/user-guide/platform-functionality/role.html +887 -83
  623. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9137 -0
  624. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +887 -83
  625. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +8933 -0
  626. nautobot/project-static/docs/user-guide/platform-functionality/status.html +884 -80
  627. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +884 -80
  628. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +942 -113
  629. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +884 -80
  630. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +884 -80
  631. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +884 -80
  632. nautobot/project-static/js/forms.js +71 -0
  633. nautobot/project-static/js/table_sorting_indicator.js +46 -0
  634. nautobot/project-static/js/tableconfig.js +6 -1
  635. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +3 -0
  636. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.eot +0 -0
  637. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.ttf +0 -0
  638. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff +0 -0
  639. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 +0 -0
  640. nautobot/tenancy/__init__.py +0 -1
  641. nautobot/tenancy/apps.py +1 -0
  642. nautobot/tenancy/factory.py +3 -2
  643. nautobot/tenancy/filters/__init__.py +1 -0
  644. nautobot/tenancy/forms.py +1 -1
  645. nautobot/tenancy/templates/tenancy/tenant.html +22 -18
  646. nautobot/tenancy/views.py +11 -10
  647. nautobot/users/__init__.py +0 -1
  648. nautobot/users/api/serializers.py +1 -1
  649. nautobot/users/api/views.py +4 -2
  650. nautobot/users/apps.py +3 -2
  651. nautobot/users/factory.py +3 -3
  652. nautobot/users/migrations/0010_user_default_saved_views.py +20 -0
  653. nautobot/users/models.py +12 -0
  654. nautobot/users/tests/test_filters.py +6 -3
  655. nautobot/users/urls.py +8 -0
  656. nautobot/virtualization/__init__.py +0 -1
  657. nautobot/virtualization/apps.py +1 -0
  658. nautobot/virtualization/filters.py +6 -1
  659. nautobot/virtualization/forms.py +11 -3
  660. nautobot/virtualization/graphql/types.py +2 -2
  661. nautobot/virtualization/migrations/0029_add_role_field_to_interface_models.py +27 -0
  662. nautobot/virtualization/migrations/0030_alter_virtualmachine_local_config_context_data_owner_content_type_and_more.py +67 -0
  663. nautobot/virtualization/tables.py +15 -5
  664. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  665. nautobot/virtualization/templates/virtualization/vminterface.html +7 -1
  666. nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
  667. nautobot/virtualization/tests/test_api.py +9 -4
  668. nautobot/virtualization/tests/test_filters.py +22 -0
  669. nautobot/virtualization/tests/test_models.py +7 -3
  670. nautobot/virtualization/tests/test_views.py +19 -3
  671. nautobot/virtualization/urls.py +2 -2
  672. nautobot/virtualization/views.py +10 -32
  673. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/METADATA +21 -19
  674. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/RECORD +679 -559
  675. nautobot/project-static/materialdesignicons-6.5.95/.github/ISSUE_TEMPLATE.md +0 -3
  676. nautobot/project-static/materialdesignicons-6.5.95/README.md +0 -25
  677. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css +0 -26654
  678. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css.map +0 -16
  679. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css +0 -3
  680. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css.map +0 -16
  681. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff +0 -0
  682. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff2 +0 -0
  683. nautobot/project-static/materialdesignicons-6.5.95/package.json +0 -28
  684. nautobot/project-static/materialdesignicons-6.5.95/preview.html +0 -717
  685. nautobot/project-static/materialdesignicons-6.5.95/scss/_animated.scss +0 -27
  686. nautobot/project-static/materialdesignicons-6.5.95/scss/_core.scss +0 -10
  687. nautobot/project-static/materialdesignicons-6.5.95/scss/_extras.scss +0 -65
  688. nautobot/project-static/materialdesignicons-6.5.95/scss/_functions.scss +0 -20
  689. nautobot/project-static/materialdesignicons-6.5.95/scss/_icons.scss +0 -10
  690. nautobot/project-static/materialdesignicons-6.5.95/scss/_path.scss +0 -10
  691. nautobot/project-static/materialdesignicons-6.5.95/scss/_variables.scss +0 -6606
  692. nautobot/project-static/materialdesignicons-6.5.95/scss/materialdesignicons.scss +0 -8
  693. /nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/LICENSE +0 -0
  694. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/LICENSE.txt +0 -0
  695. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/NOTICE +0 -0
  696. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/WHEEL +0 -0
  697. {nautobot-2.2.9.dist-info → nautobot-2.3.0b1.dist-info}/entry_points.txt +0 -0
@@ -7,6 +7,7 @@ from django.core.exceptions import FieldError, ValidationError
7
7
  from django.db.models import ForeignKey
8
8
  from django.utils.html import format_html, format_html_join
9
9
  from django.utils.safestring import mark_safe
10
+ from django_tables2 import RequestConfig
10
11
  from rest_framework import exceptions, serializers
11
12
 
12
13
  from nautobot.core.api.fields import ChoiceField, ContentTypeField, TimeZoneSerializerField
@@ -14,7 +15,9 @@ from nautobot.core.api.parsers import NautobotCSVParser
14
15
  from nautobot.core.models.utils import is_taggable
15
16
  from nautobot.core.utils.data import is_uuid
16
17
  from nautobot.core.utils.filtering import get_filter_field_label
17
- from nautobot.core.utils.lookup import get_form_for_model
18
+ from nautobot.core.utils.lookup import get_created_and_last_updated_usernames_for_model, get_form_for_model
19
+ from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
20
+ from nautobot.extras.tables import AssociatedContactsTable, DynamicGroupTable, ObjectMetadataTable
18
21
 
19
22
 
20
23
  def check_filter_for_display(filters, field_name, values):
@@ -291,3 +294,78 @@ def prepare_cloned_fields(instance):
291
294
  param_string = urllib.parse.urlencode(params)
292
295
 
293
296
  return param_string
297
+
298
+
299
+ def view_changes_not_saved(request, view, current_saved_view):
300
+ """
301
+ Compare request.GET's query dict with the configuration stored on the current saved view
302
+ If there is any configuration different, return True
303
+ If every configuration is the same, return False
304
+ """
305
+ if current_saved_view is None:
306
+ return True
307
+ query_dict = request.GET.dict()
308
+
309
+ if "table_changes_pending" in query_dict or "all_filters_removed" in query_dict:
310
+ return True
311
+ per_page = int(query_dict.get("per_page", 0))
312
+ if per_page and per_page != current_saved_view.config.get("pagination_count"):
313
+ return True
314
+ sort = request.GET.getlist("sort", [])
315
+ if sort and sort != current_saved_view.config.get("sort_order", []):
316
+ return True
317
+ query_dict_keys = sorted(list(query_dict.keys()))
318
+ for param in view.non_filter_params:
319
+ if param in query_dict_keys:
320
+ query_dict_keys.remove(param)
321
+ filter_params = current_saved_view.config.get("filter_params", {})
322
+
323
+ if query_dict_keys:
324
+ if set(query_dict_keys) != set(filter_params.keys()):
325
+ return True
326
+ for key, value in filter_params.items():
327
+ if set(value) != set(request.GET.getlist(key)):
328
+ return True
329
+ return False
330
+
331
+
332
+ def common_detail_view_context(request, instance):
333
+ """Additional template context for object detail views, shared by both ObjectView and NautobotHTMLRenderer."""
334
+ context = {}
335
+
336
+ created_by, last_updated_by = get_created_and_last_updated_usernames_for_model(instance)
337
+ context["created_by"] = created_by
338
+ context["last_updated_by"] = last_updated_by
339
+
340
+ if instance.is_contact_associable_model:
341
+ paginate = {"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
342
+ associations = instance.associated_contacts.restrict(request.user, "view").order_by("role__name")
343
+ associations_table = AssociatedContactsTable(associations, orderable=False)
344
+ RequestConfig(request, paginate).configure(associations_table)
345
+ associations_table.columns.show("pk")
346
+ context["associated_contacts_table"] = associations_table
347
+ else:
348
+ context["associated_contacts_table"] = None
349
+
350
+ if instance.is_dynamic_group_associable_model:
351
+ paginate = {"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
352
+ dynamic_groups = instance.dynamic_groups.restrict(request.user, "view")
353
+ dynamic_groups_table = DynamicGroupTable(dynamic_groups, orderable=False)
354
+ dynamic_groups_table.columns.hide("content_type")
355
+ RequestConfig(request, paginate).configure(dynamic_groups_table)
356
+ # dynamic_groups_table.columns.show("pk") # we don't have any supported bulk ops here presently
357
+ context["associated_dynamic_groups_table"] = dynamic_groups_table
358
+ else:
359
+ context["associated_dynamic_groups_table"] = None
360
+
361
+ if instance.is_metadata_associable_model:
362
+ paginate = {"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
363
+ object_metadatas = instance.associated_object_metadatas.restrict(request.user, "view").order_by("scoped_fields")
364
+ object_metadatas_table = ObjectMetadataTable(object_metadatas, orderable=False)
365
+ object_metadatas_table.columns.hide("assigned_object")
366
+ RequestConfig(request, paginate).configure(object_metadatas_table)
367
+ context["associated_object_metadatas_table"] = object_metadatas_table
368
+ else:
369
+ context["associated_object_metadatas_table"] = None
370
+
371
+ return context
nautobot/dcim/__init__.py CHANGED
@@ -1 +0,0 @@
1
- default_app_config = "nautobot.dcim.apps.DCIMConfig"
@@ -3,7 +3,7 @@ import contextlib
3
3
  from django.contrib.contenttypes.models import ContentType
4
4
  from drf_spectacular.utils import extend_schema_field
5
5
  from rest_framework import serializers
6
- from rest_framework.validators import UniqueTogetherValidator
6
+ from rest_framework.validators import UniqueTogetherValidator, UniqueValidator
7
7
 
8
8
  from nautobot.core.api import (
9
9
  ChoiceField,
@@ -73,6 +73,10 @@ from nautobot.dcim.models import (
73
73
  Location,
74
74
  LocationType,
75
75
  Manufacturer,
76
+ Module,
77
+ ModuleBay,
78
+ ModuleBayTemplate,
79
+ ModuleType,
76
80
  PathEndpoint,
77
81
  Platform,
78
82
  PowerFeed,
@@ -176,12 +180,40 @@ class ConnectedEndpointSerializer(PathEndpointModelSerializerMixin):
176
180
  pass
177
181
 
178
182
 
183
+ class ModularDeviceComponentTemplateSerializerMixin:
184
+ def validate(self, data):
185
+ """Validate device_type and module_type field constraints for modular device component templates."""
186
+ if data.get("device_type") and data.get("module_type"):
187
+ raise serializers.ValidationError("Only one of device_type or module_type must be set")
188
+ if data.get("device_type"):
189
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("device_type", "name"))
190
+ validator(data, self)
191
+ if data.get("module_type"):
192
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("module_type", "name"))
193
+ validator(data, self)
194
+ return super().validate(data)
195
+
196
+
197
+ class ModularDeviceComponentSerializerMixin:
198
+ def validate(self, data):
199
+ """Validate device and module field constraints for modular device components."""
200
+ if data.get("device") and data.get("module"):
201
+ raise serializers.ValidationError("Only one of device or module must be set")
202
+ if data.get("device"):
203
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("device", "name"))
204
+ validator(data, self)
205
+ if data.get("module"):
206
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("module", "name"))
207
+ validator(data, self)
208
+ return super().validate(data)
209
+
210
+
179
211
  #
180
212
  # Locations
181
213
  #
182
214
 
183
215
 
184
- class LocationTypeSerializer(NautobotModelSerializer, TreeModelSerializerMixin):
216
+ class LocationTypeSerializer(TreeModelSerializerMixin, NautobotModelSerializer):
185
217
  content_types = ContentTypeField(
186
218
  queryset=ContentType.objects.filter(FeatureQuery("locations").get_query()),
187
219
  required=False,
@@ -195,9 +227,9 @@ class LocationTypeSerializer(NautobotModelSerializer, TreeModelSerializerMixin):
195
227
 
196
228
 
197
229
  class LocationSerializer(
198
- NautobotModelSerializer,
199
230
  TaggedModelSerializerMixin,
200
231
  TreeModelSerializerMixin,
232
+ NautobotModelSerializer,
201
233
  ):
202
234
  time_zone = TimeZoneSerializerField(required=False, allow_null=True)
203
235
  circuit_count = serializers.IntegerField(read_only=True)
@@ -258,7 +290,7 @@ class LocationSerializer(
258
290
  #
259
291
 
260
292
 
261
- class RackGroupSerializer(NautobotModelSerializer, TreeModelSerializerMixin):
293
+ class RackGroupSerializer(TreeModelSerializerMixin, NautobotModelSerializer):
262
294
  rack_count = serializers.IntegerField(read_only=True)
263
295
 
264
296
  class Meta:
@@ -267,10 +299,7 @@ class RackGroupSerializer(NautobotModelSerializer, TreeModelSerializerMixin):
267
299
  list_display_fields = ["name", "location", "rack_count", "description"]
268
300
 
269
301
 
270
- class RackSerializer(
271
- NautobotModelSerializer,
272
- TaggedModelSerializerMixin,
273
- ):
302
+ class RackSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
274
303
  type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False)
275
304
  width = ChoiceField(choices=RackWidthChoices, required=False, help_text="Rail-to-rail width (in inches)")
276
305
  outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False)
@@ -326,7 +355,7 @@ class RackUnitSerializer(serializers.Serializer):
326
355
  occupied = serializers.BooleanField(read_only=True)
327
356
 
328
357
 
329
- class RackReservationSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
358
+ class RackReservationSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
330
359
  class Meta:
331
360
  model = RackReservation
332
361
  fields = "__all__"
@@ -373,6 +402,7 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
373
402
 
374
403
 
375
404
  class ManufacturerSerializer(NautobotModelSerializer):
405
+ cloud_account_count = serializers.IntegerField(read_only=True)
376
406
  device_type_count = serializers.IntegerField(read_only=True)
377
407
  inventory_item_count = serializers.IntegerField(read_only=True)
378
408
  platform_count = serializers.IntegerField(read_only=True)
@@ -392,7 +422,7 @@ class DeviceFamilySerializer(NautobotModelSerializer):
392
422
  list_display_fields = ["name", "device_type_count", "description"]
393
423
 
394
424
 
395
- class DeviceTypeSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
425
+ class DeviceTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
396
426
  subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
397
427
  front_image = serializers.ImageField(allow_null=True, required=False)
398
428
  rear_image = serializers.ImageField(allow_null=True, required=False)
@@ -430,20 +460,22 @@ class DeviceTypeSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
430
460
  }
431
461
 
432
462
 
433
- class ConsolePortTemplateSerializer(NautobotModelSerializer):
463
+ class ConsolePortTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
434
464
  type = ChoiceField(choices=ConsolePortTypeChoices, allow_blank=True, required=False)
435
465
 
436
466
  class Meta:
437
467
  model = ConsolePortTemplate
438
468
  fields = "__all__"
469
+ validators = []
439
470
 
440
471
 
441
- class ConsoleServerPortTemplateSerializer(NautobotModelSerializer):
472
+ class ConsoleServerPortTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
442
473
  type = ChoiceField(choices=ConsolePortTypeChoices, allow_blank=True, required=False)
443
474
 
444
475
  class Meta:
445
476
  model = ConsoleServerPortTemplate
446
477
  fields = "__all__"
478
+ validators = []
447
479
 
448
480
 
449
481
  #
@@ -461,7 +493,7 @@ class InterfaceRedundancyGroupAssociationSerializer(ValidatedModelSerializer):
461
493
  fields = "__all__"
462
494
 
463
495
 
464
- class InterfaceRedundancyGroupSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
496
+ class InterfaceRedundancyGroupSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
465
497
  """InterfaceRedundancyGroup Serializer."""
466
498
 
467
499
  protocol = ChoiceField(choices=InterfaceRedundancyGroupProtocolChoices)
@@ -476,45 +508,55 @@ class InterfaceRedundancyGroupSerializer(NautobotModelSerializer, TaggedModelSer
476
508
  }
477
509
 
478
510
 
479
- class PowerPortTemplateSerializer(NautobotModelSerializer):
511
+ class PowerPortTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
480
512
  type = ChoiceField(choices=PowerPortTypeChoices, allow_blank=True, required=False)
481
513
 
482
514
  class Meta:
483
515
  model = PowerPortTemplate
484
516
  fields = "__all__"
517
+ validators = []
485
518
 
486
519
 
487
- class PowerOutletTemplateSerializer(NautobotModelSerializer):
520
+ class PowerOutletTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
488
521
  type = ChoiceField(choices=PowerOutletTypeChoices, allow_blank=True, required=False)
489
522
  feed_leg = ChoiceField(choices=PowerOutletFeedLegChoices, allow_blank=True, required=False)
490
523
 
491
524
  class Meta:
492
525
  model = PowerOutletTemplate
493
526
  fields = "__all__"
527
+ validators = []
494
528
 
495
529
 
496
- class InterfaceTemplateSerializer(NautobotModelSerializer):
530
+ class InterfaceTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
497
531
  type = ChoiceField(choices=InterfaceTypeChoices)
498
532
 
499
533
  class Meta:
500
534
  model = InterfaceTemplate
501
535
  fields = "__all__"
536
+ validators = []
502
537
 
503
538
 
504
- class RearPortTemplateSerializer(NautobotModelSerializer):
539
+ class RearPortTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
505
540
  type = ChoiceField(choices=PortTypeChoices)
506
541
 
507
542
  class Meta:
508
543
  model = RearPortTemplate
509
544
  fields = "__all__"
545
+ validators = []
510
546
 
511
547
 
512
- class FrontPortTemplateSerializer(NautobotModelSerializer):
548
+ class FrontPortTemplateSerializer(ModularDeviceComponentTemplateSerializerMixin, NautobotModelSerializer):
513
549
  type = ChoiceField(choices=PortTypeChoices)
514
550
 
515
551
  class Meta:
516
552
  model = FrontPortTemplate
517
553
  fields = "__all__"
554
+ validators = [
555
+ UniqueTogetherValidator(
556
+ queryset=FrontPortTemplate.objects.all(),
557
+ fields=("rear_port_template", "rear_port_position"),
558
+ ),
559
+ ]
518
560
 
519
561
 
520
562
  class DeviceBayTemplateSerializer(NautobotModelSerializer):
@@ -550,13 +592,13 @@ class PlatformSerializer(NautobotModelSerializer):
550
592
  ]
551
593
 
552
594
 
553
- class DeviceBaySerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
595
+ class DeviceBaySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
554
596
  class Meta:
555
597
  model = DeviceBay
556
598
  fields = "__all__"
557
599
 
558
600
 
559
- class DeviceSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
601
+ class DeviceSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
560
602
  face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, required=False)
561
603
  config_context = serializers.SerializerMethodField()
562
604
 
@@ -651,10 +693,11 @@ class DeviceNAPALMSerializer(serializers.Serializer):
651
693
 
652
694
 
653
695
  class ConsoleServerPortSerializer(
654
- NautobotModelSerializer,
696
+ ModularDeviceComponentSerializerMixin,
655
697
  TaggedModelSerializerMixin,
656
698
  CableTerminationModelSerializerMixin,
657
699
  PathEndpointModelSerializerMixin,
700
+ NautobotModelSerializer,
658
701
  ):
659
702
  type = ChoiceField(choices=ConsolePortTypeChoices, allow_blank=True, required=False)
660
703
 
@@ -662,13 +705,15 @@ class ConsoleServerPortSerializer(
662
705
  model = ConsoleServerPort
663
706
  fields = "__all__"
664
707
  extra_kwargs = {"cable": {"read_only": True}}
708
+ validators = []
665
709
 
666
710
 
667
711
  class ConsolePortSerializer(
668
- NautobotModelSerializer,
712
+ ModularDeviceComponentSerializerMixin,
669
713
  TaggedModelSerializerMixin,
670
714
  CableTerminationModelSerializerMixin,
671
715
  PathEndpointModelSerializerMixin,
716
+ NautobotModelSerializer,
672
717
  ):
673
718
  type = ChoiceField(choices=ConsolePortTypeChoices, allow_blank=True, required=False)
674
719
 
@@ -676,13 +721,15 @@ class ConsolePortSerializer(
676
721
  model = ConsolePort
677
722
  fields = "__all__"
678
723
  extra_kwargs = {"cable": {"read_only": True}}
724
+ validators = []
679
725
 
680
726
 
681
727
  class PowerOutletSerializer(
682
- NautobotModelSerializer,
728
+ ModularDeviceComponentSerializerMixin,
683
729
  TaggedModelSerializerMixin,
684
730
  CableTerminationModelSerializerMixin,
685
731
  PathEndpointModelSerializerMixin,
732
+ NautobotModelSerializer,
686
733
  ):
687
734
  type = ChoiceField(choices=PowerOutletTypeChoices, allow_blank=True, required=False)
688
735
  feed_leg = ChoiceField(choices=PowerOutletFeedLegChoices, allow_blank=True, required=False)
@@ -691,13 +738,15 @@ class PowerOutletSerializer(
691
738
  model = PowerOutlet
692
739
  fields = "__all__"
693
740
  extra_kwargs = {"cable": {"read_only": True}}
741
+ validators = []
694
742
 
695
743
 
696
744
  class PowerPortSerializer(
697
- NautobotModelSerializer,
745
+ ModularDeviceComponentSerializerMixin,
698
746
  TaggedModelSerializerMixin,
699
747
  CableTerminationModelSerializerMixin,
700
748
  PathEndpointModelSerializerMixin,
749
+ NautobotModelSerializer,
701
750
  ):
702
751
  type = ChoiceField(choices=PowerPortTypeChoices, allow_blank=True, required=False)
703
752
 
@@ -705,9 +754,10 @@ class PowerPortSerializer(
705
754
  model = PowerPort
706
755
  fields = "__all__"
707
756
  extra_kwargs = {"cable": {"read_only": True}}
757
+ validators = []
708
758
 
709
759
 
710
- class InterfaceCommonSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
760
+ class InterfaceCommonSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
711
761
  def validate(self, data):
712
762
  # Validate many-to-many VLAN assignments
713
763
  mode = data.get("mode", getattr(self.instance, "mode", None))
@@ -727,9 +777,10 @@ class InterfaceCommonSerializer(NautobotModelSerializer, TaggedModelSerializerMi
727
777
 
728
778
 
729
779
  class InterfaceSerializer(
730
- InterfaceCommonSerializer,
780
+ ModularDeviceComponentSerializerMixin,
731
781
  CableTerminationModelSerializerMixin,
732
782
  PathEndpointModelSerializerMixin,
783
+ InterfaceCommonSerializer,
733
784
  ):
734
785
  type = ChoiceField(choices=InterfaceTypeChoices)
735
786
  mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
@@ -741,6 +792,7 @@ class InterfaceSerializer(
741
792
  fields = "__all__"
742
793
  list_display_fields = ["device", "name", "status", "label", "enabled", "type", "description"]
743
794
  extra_kwargs = {"cable": {"read_only": True}}
795
+ validators = []
744
796
 
745
797
  def validate(self, data):
746
798
  # Validate many-to-many VLAN assignments
@@ -759,28 +811,42 @@ class InterfaceSerializer(
759
811
  return super().validate(data)
760
812
 
761
813
 
762
- class RearPortSerializer(NautobotModelSerializer, TaggedModelSerializerMixin, CableTerminationModelSerializerMixin):
814
+ class RearPortSerializer(
815
+ ModularDeviceComponentSerializerMixin,
816
+ TaggedModelSerializerMixin,
817
+ CableTerminationModelSerializerMixin,
818
+ NautobotModelSerializer,
819
+ ):
763
820
  type = ChoiceField(choices=PortTypeChoices)
764
821
 
765
822
  class Meta:
766
823
  model = RearPort
767
824
  fields = "__all__"
768
825
  extra_kwargs = {"cable": {"read_only": True}}
826
+ validators = []
769
827
 
770
828
 
771
- class FrontPortSerializer(NautobotModelSerializer, TaggedModelSerializerMixin, CableTerminationModelSerializerMixin):
829
+ class FrontPortSerializer(
830
+ ModularDeviceComponentSerializerMixin,
831
+ TaggedModelSerializerMixin,
832
+ CableTerminationModelSerializerMixin,
833
+ NautobotModelSerializer,
834
+ ):
772
835
  type = ChoiceField(choices=PortTypeChoices)
773
836
 
774
837
  class Meta:
775
838
  model = FrontPort
776
839
  fields = "__all__"
777
840
  extra_kwargs = {"cable": {"read_only": True}}
841
+ validators = [
842
+ UniqueTogetherValidator(
843
+ queryset=FrontPort.objects.all(),
844
+ fields=("rear_port", "rear_port_position"),
845
+ ),
846
+ ]
778
847
 
779
848
 
780
- class DeviceRedundancyGroupSerializer(
781
- NautobotModelSerializer,
782
- TaggedModelSerializerMixin,
783
- ):
849
+ class DeviceRedundancyGroupSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
784
850
  failover_strategy = ChoiceField(
785
851
  choices=DeviceRedundancyGroupFailoverStrategyChoices,
786
852
  allow_blank=True,
@@ -798,7 +864,7 @@ class DeviceRedundancyGroupSerializer(
798
864
  #
799
865
 
800
866
 
801
- class InventoryItemSerializer(NautobotModelSerializer, TaggedModelSerializerMixin, TreeModelSerializerMixin):
867
+ class InventoryItemSerializer(TaggedModelSerializerMixin, TreeModelSerializerMixin, NautobotModelSerializer):
802
868
  class Meta:
803
869
  model = InventoryItem
804
870
  fields = "__all__"
@@ -824,10 +890,7 @@ class InventoryItemSerializer(NautobotModelSerializer, TaggedModelSerializerMixi
824
890
  #
825
891
 
826
892
 
827
- class CableSerializer(
828
- NautobotModelSerializer,
829
- TaggedModelSerializerMixin,
830
- ):
893
+ class CableSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
831
894
  # TODO: termination_a_type/termination_b_type are a bit redundant with the full termination_a/termination_b dicts
832
895
  termination_a_type = ContentTypeField(queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS))
833
896
  termination_b_type = ContentTypeField(queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS))
@@ -983,7 +1046,7 @@ class InterfaceConnectionSerializer(ValidatedModelSerializer):
983
1046
  #
984
1047
 
985
1048
 
986
- class VirtualChassisSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1049
+ class VirtualChassisSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
987
1050
  member_count = serializers.IntegerField(read_only=True)
988
1051
 
989
1052
  class Meta:
@@ -997,7 +1060,7 @@ class VirtualChassisSerializer(NautobotModelSerializer, TaggedModelSerializerMix
997
1060
  #
998
1061
 
999
1062
 
1000
- class PowerPanelSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1063
+ class PowerPanelSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1001
1064
  power_feed_count = serializers.IntegerField(read_only=True)
1002
1065
 
1003
1066
  class Meta:
@@ -1006,10 +1069,10 @@ class PowerPanelSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1006
1069
 
1007
1070
 
1008
1071
  class PowerFeedSerializer(
1009
- NautobotModelSerializer,
1010
1072
  TaggedModelSerializerMixin,
1011
1073
  CableTerminationModelSerializerMixin,
1012
1074
  PathEndpointModelSerializerMixin,
1075
+ NautobotModelSerializer,
1013
1076
  ):
1014
1077
  type = ChoiceField(choices=PowerFeedTypeChoices, default=PowerFeedTypeChoices.TYPE_PRIMARY)
1015
1078
  supply = ChoiceField(choices=PowerFeedSupplyChoices, default=PowerFeedSupplyChoices.SUPPLY_AC)
@@ -1025,13 +1088,13 @@ class PowerFeedSerializer(
1025
1088
  #
1026
1089
 
1027
1090
 
1028
- class SoftwareImageFileSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1091
+ class SoftwareImageFileSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1029
1092
  class Meta:
1030
1093
  model = SoftwareImageFile
1031
1094
  fields = "__all__"
1032
1095
 
1033
1096
 
1034
- class SoftwareVersionSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1097
+ class SoftwareVersionSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1035
1098
  class Meta:
1036
1099
  model = SoftwareVersion
1037
1100
  fields = "__all__"
@@ -1043,13 +1106,86 @@ class DeviceTypeToSoftwareImageFileSerializer(ValidatedModelSerializer):
1043
1106
  fields = "__all__"
1044
1107
 
1045
1108
 
1046
- class ControllerSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1109
+ class ControllerSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1047
1110
  class Meta:
1048
1111
  model = Controller
1049
1112
  fields = "__all__"
1050
1113
 
1051
1114
 
1052
- class ControllerManagedDeviceGroupSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
1115
+ class ControllerManagedDeviceGroupSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1053
1116
  class Meta:
1054
1117
  model = ControllerManagedDeviceGroup
1055
1118
  fields = "__all__"
1119
+
1120
+
1121
+ #
1122
+ # Modules
1123
+ #
1124
+
1125
+
1126
+ class ModuleBaySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1127
+ class Meta:
1128
+ model = ModuleBay
1129
+ fields = "__all__"
1130
+ validators = []
1131
+
1132
+ def validate(self, data):
1133
+ """Validate device and module field constraints for module bay."""
1134
+ if data.get("parent_device") and data.get("parent_module"):
1135
+ raise serializers.ValidationError("Only one of parent_device or parent_module must be set")
1136
+ if data.get("parent_device"):
1137
+ validator = UniqueTogetherValidator(
1138
+ queryset=self.Meta.model.objects.all(), fields=("parent_device", "name")
1139
+ )
1140
+ validator(data, self)
1141
+ if data.get("parent_module"):
1142
+ validator = UniqueTogetherValidator(
1143
+ queryset=self.Meta.model.objects.all(), fields=("parent_module", "name")
1144
+ )
1145
+ validator(data, self)
1146
+ return super().validate(data)
1147
+
1148
+
1149
+ class ModuleBayTemplateSerializer(NautobotModelSerializer):
1150
+ class Meta:
1151
+ model = ModuleBayTemplate
1152
+ fields = "__all__"
1153
+ validators = []
1154
+
1155
+ def validate(self, data):
1156
+ """Validate device_type and module_type field constraints for module bay template."""
1157
+ if data.get("device_type") and data.get("module_type"):
1158
+ raise serializers.ValidationError("Only one of device_type or module_type must be set")
1159
+ if data.get("device_type"):
1160
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("device_type", "name"))
1161
+ validator(data, self)
1162
+ if data.get("module_type"):
1163
+ validator = UniqueTogetherValidator(queryset=self.Meta.model.objects.all(), fields=("module_type", "name"))
1164
+ validator(data, self)
1165
+ return super().validate(data)
1166
+
1167
+
1168
+ class ModuleSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1169
+ class Meta:
1170
+ model = Module
1171
+ fields = "__all__"
1172
+
1173
+ validators = []
1174
+
1175
+ def validate(self, data):
1176
+ """Validate asset_Tag, serial, parent_module_bay and location field constraints for module."""
1177
+ if data.get("parent_module_bay") and data.get("location"):
1178
+ raise serializers.ValidationError("Only one of parent_module_bay or location must be set")
1179
+ if data.get("serial"):
1180
+ validator = UniqueTogetherValidator(queryset=Module.objects.all(), fields=("module_type", "serial"))
1181
+ validator(data, self)
1182
+ if data.get("asset_tag"):
1183
+ validator = UniqueValidator(queryset=Module.objects.all())
1184
+ validator(data["asset_tag"], self.fields["asset_tag"])
1185
+ return super().validate(data)
1186
+
1187
+
1188
+ class ModuleTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1189
+ class Meta:
1190
+ model = ModuleType
1191
+ fields = "__all__"
nautobot/dcim/api/urls.py CHANGED
@@ -13,12 +13,13 @@ router.register("rack-groups", views.RackGroupViewSet)
13
13
  router.register("racks", views.RackViewSet)
14
14
  router.register("rack-reservations", views.RackReservationViewSet)
15
15
 
16
- # Device types
16
+ # Device types and Module types
17
17
  router.register("manufacturers", views.ManufacturerViewSet)
18
18
  router.register("device-families", views.DeviceFamilyViewSet)
19
19
  router.register("device-types", views.DeviceTypeViewSet)
20
+ router.register("module-types", views.ModuleTypeViewSet)
20
21
 
21
- # Device type components
22
+ # Device type and Module type components
22
23
  router.register("console-port-templates", views.ConsolePortTemplateViewSet)
23
24
  router.register("console-server-port-templates", views.ConsoleServerPortTemplateViewSet)
24
25
  router.register("power-port-templates", views.PowerPortTemplateViewSet)
@@ -27,10 +28,12 @@ router.register("interface-templates", views.InterfaceTemplateViewSet)
27
28
  router.register("front-port-templates", views.FrontPortTemplateViewSet)
28
29
  router.register("rear-port-templates", views.RearPortTemplateViewSet)
29
30
  router.register("device-bay-templates", views.DeviceBayTemplateViewSet)
31
+ router.register("module-bay-templates", views.ModuleBayTemplateViewSet)
30
32
 
31
- # Devices
33
+ # Devices and Modules
32
34
  router.register("platforms", views.PlatformViewSet)
33
35
  router.register("devices", views.DeviceViewSet)
36
+ router.register("modules", views.ModuleViewSet)
34
37
 
35
38
  # Device components
36
39
  router.register("console-ports", views.ConsolePortViewSet)
@@ -42,6 +45,7 @@ router.register("front-ports", views.FrontPortViewSet)
42
45
  router.register("rear-ports", views.RearPortViewSet)
43
46
  router.register("device-bays", views.DeviceBayViewSet)
44
47
  router.register("inventory-items", views.InventoryItemViewSet)
48
+ router.register("module-bays", views.ModuleBayViewSet)
45
49
 
46
50
  # Connections
47
51
  router.register("console-connections", views.ConsoleConnectionViewSet, basename="consoleconnections")