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
nautobot/apps/forms.py CHANGED
@@ -71,6 +71,7 @@ from nautobot.extras.forms import (
71
71
  CustomFieldModelBulkEditFormMixin,
72
72
  CustomFieldModelCSVForm,
73
73
  CustomFieldModelFormMixin,
74
+ DynamicGroupModelFormMixin,
74
75
  NautobotBulkEditForm,
75
76
  NautobotModelForm,
76
77
  NoteModelBulkEditFormMixin,
@@ -87,6 +88,7 @@ from nautobot.extras.forms.forms import (
87
88
  provider_choices_with_blank,
88
89
  )
89
90
  from nautobot.extras.forms.mixins import (
91
+ ContactTeamModelFilterFormMixin,
90
92
  CustomFieldModelFilterFormMixin,
91
93
  NoteFormBase,
92
94
  RelationshipModelFilterFormMixin,
@@ -109,6 +111,7 @@ __all__ = (
109
111
  "ColorSelect",
110
112
  "CommentField",
111
113
  "ConfirmationForm",
114
+ "ContactTeamModelFilterFormMixin",
112
115
  "ContentTypeSelect",
113
116
  "CSVChoiceField",
114
117
  "CSVContentTypeField",
@@ -126,6 +129,7 @@ __all__ = (
126
129
  "DateTimePicker",
127
130
  "dynamic_formset_factory",
128
131
  "DynamicFilterForm",
132
+ "DynamicGroupModelFormMixin",
129
133
  "DynamicModelChoiceField",
130
134
  "DynamicModelChoiceMixin",
131
135
  "DynamicModelMultipleChoiceField",
nautobot/apps/models.py CHANGED
@@ -44,7 +44,13 @@ from nautobot.extras.models import (
44
44
  StatusField,
45
45
  StatusModel,
46
46
  )
47
- from nautobot.extras.models.mixins import DynamicGroupMixin, NotesMixin
47
+ from nautobot.extras.models.mixins import (
48
+ ContactMixin,
49
+ DynamicGroupMixin,
50
+ DynamicGroupsModelMixin,
51
+ NotesMixin,
52
+ SavedViewMixin,
53
+ )
48
54
  from nautobot.extras.models.models import ConfigContextSchemaValidationMixin
49
55
  from nautobot.extras.plugins import CustomValidator
50
56
  from nautobot.extras.utils import extras_features
@@ -65,12 +71,14 @@ __all__ = (
65
71
  "ConfigContextSchemaValidationMixin",
66
72
  "construct_composite_key",
67
73
  "construct_natural_slug",
74
+ "ContactMixin",
68
75
  "ContentTypeRelatedQuerySet",
69
76
  "count_related",
70
77
  "CustomFieldModel",
71
78
  "CustomValidator",
72
79
  "deconstruct_composite_key",
73
80
  "DynamicGroupMixin",
81
+ "DynamicGroupsModelMixin",
74
82
  "EmptyGroupByJSONBAgg",
75
83
  "EnhancedURLValidator",
76
84
  "ExclusionValidator",
@@ -97,6 +105,7 @@ __all__ = (
97
105
  "PrimaryModel",
98
106
  "RelationshipModel",
99
107
  "RestrictedQuerySet",
108
+ "SavedViewMixin",
100
109
  "serialize_object_v2",
101
110
  "serialize_object",
102
111
  "slugify_dashes_to_underscores",
@@ -1 +0,0 @@
1
- default_app_config = "nautobot.circuits.apps.CircuitsConfig"
nautobot/circuits/apps.py CHANGED
@@ -2,6 +2,7 @@ from nautobot.core.apps import NautobotConfig
2
2
 
3
3
 
4
4
  class CircuitsConfig(NautobotConfig):
5
+ default = True
5
6
  name = "nautobot.circuits"
6
7
  verbose_name = "Circuits"
7
8
  searchable_models = [
@@ -3,6 +3,7 @@ import faker
3
3
 
4
4
  from nautobot.circuits import choices
5
5
  from nautobot.circuits.models import Circuit, CircuitTermination, CircuitType, Provider, ProviderNetwork
6
+ from nautobot.cloud.models import CloudNetwork
6
7
  from nautobot.core.factory import (
7
8
  NautobotBoolIterator,
8
9
  OrganizationalModelFactory,
@@ -83,9 +84,7 @@ class ProviderNetworkFactory(PrimaryModelFactory):
83
84
  model = ProviderNetwork
84
85
  exclude = ("has_description", "has_comments")
85
86
 
86
- name = factory.LazyAttribute(
87
- lambda o: f"{o.provider.name} Network {faker.Faker().word(part_of_speech='noun')}"[:100]
88
- )
87
+ name = factory.LazyAttributeSequence(lambda o, n: f"{o.provider.name} Network {n + 1}"[:100])
89
88
  provider = random_instance(Provider, allow_null=False)
90
89
 
91
90
  has_description = NautobotBoolIterator()
@@ -105,6 +104,7 @@ class CircuitTerminationFactory(PrimaryModelFactory):
105
104
  "has_xconnect_id",
106
105
  "has_pp_info",
107
106
  "has_description",
107
+ "has_cloud_network",
108
108
  )
109
109
 
110
110
  circuit = factory.LazyAttribute(
@@ -122,11 +122,23 @@ class CircuitTerminationFactory(PrimaryModelFactory):
122
122
  None,
123
123
  )
124
124
 
125
+ has_cloud_network = factory.Faker("pybool")
126
+
127
+ @factory.lazy_attribute
128
+ def cloud_network(self):
129
+ if not self.has_cloud_network:
130
+ return None
131
+ if self.has_location:
132
+ return None
133
+ return faker.Faker().random_element(elements=CloudNetwork.objects.all())
134
+
125
135
  @factory.lazy_attribute
126
136
  def provider_network(self):
127
137
  # location and provider_network are mutually exclusive but cannot both be null
128
138
  if self.has_location:
129
139
  return None
140
+ if self.has_cloud_network:
141
+ return None
130
142
  if ProviderNetwork.objects.filter(provider=self.circuit.provider).exists():
131
143
  return faker.Faker().random_element(elements=ProviderNetwork.objects.filter(provider=self.circuit.provider))
132
144
  return ProviderNetworkFactory(provider=self.circuit.provider)
@@ -1,5 +1,6 @@
1
1
  import django_filters
2
2
 
3
+ from nautobot.cloud.models import CloudNetwork
3
4
  from nautobot.core.filters import (
4
5
  BaseFilterSet,
5
6
  NameSearchFilterSet,
@@ -57,6 +58,7 @@ class ProviderFilterSet(NautobotFilterSet):
57
58
  label="Has provider networks",
58
59
  )
59
60
  location = TreeNodeMultipleChoiceFilter(
61
+ prefers_id=True,
60
62
  field_name="circuits__circuit_terminations__location",
61
63
  queryset=Location.objects.all(),
62
64
  to_field_name="name",
@@ -140,6 +142,7 @@ class CircuitFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMode
140
142
  label="Circuit type (name or ID)",
141
143
  )
142
144
  location = TreeNodeMultipleChoiceFilter(
145
+ prefers_id=True,
143
146
  field_name="circuit_terminations__location",
144
147
  queryset=Location.objects.all(),
145
148
  to_field_name="name",
@@ -158,6 +161,13 @@ class CircuitFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMode
158
161
  label="Termination Z (ID)",
159
162
  )
160
163
 
164
+ cloud_network = NaturalKeyOrPKMultipleChoiceFilter(
165
+ field_name="circuit_terminations__cloud_network",
166
+ queryset=CloudNetwork.objects.all(),
167
+ to_field_name="name",
168
+ label="Cloud Network (name or ID)",
169
+ )
170
+
161
171
  class Meta:
162
172
  model = Circuit
163
173
  fields = [
@@ -196,6 +206,9 @@ class CircuitTerminationFilterSet(
196
206
  to_field_name="name",
197
207
  label="Provider Network (name or ID)",
198
208
  )
209
+ cloud_network = NaturalKeyOrPKMultipleChoiceFilter(
210
+ queryset=CloudNetwork.objects.all(), to_field_name="name", label="Cloud Network (name or ID)"
211
+ )
199
212
 
200
213
  class Meta:
201
214
  model = CircuitTermination
@@ -1,5 +1,6 @@
1
1
  from django import forms
2
2
 
3
+ from nautobot.cloud.models import CloudNetwork
3
4
  from nautobot.core.constants import CHARFIELD_MAX_LENGTH
4
5
  from nautobot.core.forms import (
5
6
  CommentField,
@@ -215,6 +216,7 @@ class CircuitFilterForm(
215
216
  "circuit_type",
216
217
  "provider",
217
218
  "provider_network",
219
+ "cloud_network",
218
220
  "status",
219
221
  "location",
220
222
  "tenant_group",
@@ -233,6 +235,12 @@ class CircuitFilterForm(
233
235
  to_field_name="name",
234
236
  label="Provider Network",
235
237
  )
238
+ cloud_network = DynamicModelMultipleChoiceField(
239
+ queryset=CloudNetwork.objects.all(),
240
+ required=False,
241
+ to_field_name="name",
242
+ label="Cloud Network",
243
+ )
236
244
  commit_rate = forms.IntegerField(required=False, min_value=0, label="Commit rate (Kbps)")
237
245
  tags = TagFilterField(model)
238
246
 
@@ -246,6 +254,7 @@ class CircuitTerminationForm(LocatableModelFormMixin, NautobotModelForm):
246
254
  provider_network = DynamicModelChoiceField(
247
255
  queryset=ProviderNetwork.objects.all(), required=False, label="Provider Network"
248
256
  )
257
+ cloud_network = DynamicModelChoiceField(queryset=CloudNetwork.objects.all(), required=False, label="Cloud Network")
249
258
 
250
259
  class Meta:
251
260
  model = CircuitTermination
@@ -253,6 +262,7 @@ class CircuitTerminationForm(LocatableModelFormMixin, NautobotModelForm):
253
262
  "term_side",
254
263
  "location",
255
264
  "provider_network",
265
+ "cloud_network",
256
266
  "port_speed",
257
267
  "upstream_speed",
258
268
  "xconnect_id",
@@ -277,3 +287,6 @@ class CircuitTerminationFilterForm(LocatableModelFilterFormMixin, NautobotFilter
277
287
  provider_network = DynamicModelMultipleChoiceField(
278
288
  queryset=ProviderNetwork.objects.all(), to_field_name="name", required=False
279
289
  )
290
+ cloud_network = DynamicModelMultipleChoiceField(
291
+ queryset=CloudNetwork.objects.all(), to_field_name="name", required=False
292
+ )
@@ -0,0 +1,32 @@
1
+ # Generated by Django 4.2.9 on 2024-01-17 18:52
2
+
3
+ from django.db import migrations
4
+ import django.db.models.deletion
5
+
6
+ import nautobot.core.models.fields
7
+ import nautobot.extras.models.statuses
8
+
9
+
10
+ class Migration(migrations.Migration):
11
+ dependencies = [
12
+ ("extras", "0104_contact_contactassociation_team"),
13
+ ("dcim", "0053_create_device_family_model"),
14
+ ("circuits", "0020_update_all_charfields_max_length_to_255"),
15
+ ]
16
+
17
+ operations = [
18
+ migrations.AlterField(
19
+ model_name="circuit",
20
+ name="status",
21
+ field=nautobot.extras.models.statuses.StatusField(
22
+ on_delete=django.db.models.deletion.PROTECT, to="extras.status"
23
+ ),
24
+ ),
25
+ migrations.AlterField(
26
+ model_name="circuittermination",
27
+ name="_path",
28
+ field=nautobot.core.models.fields.ForeignKeyWithAutoRelatedName(
29
+ blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="dcim.cablepath"
30
+ ),
31
+ ),
32
+ ]
@@ -0,0 +1,25 @@
1
+ # Generated by Django 4.2.14 on 2024-07-18 16:08
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("cloud", "0001_initial"),
10
+ ("circuits", "0021_alter_circuit_status_alter_circuittermination__path"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AddField(
15
+ model_name="circuittermination",
16
+ name="cloud_network",
17
+ field=models.ForeignKey(
18
+ blank=True,
19
+ null=True,
20
+ on_delete=django.db.models.deletion.PROTECT,
21
+ related_name="circuit_terminations",
22
+ to="cloud.cloudnetwork",
23
+ ),
24
+ ),
25
+ ]
@@ -205,6 +205,13 @@ class CircuitTermination(PrimaryModel, PathEndpoint, CableTermination):
205
205
  blank=True,
206
206
  null=True,
207
207
  )
208
+ cloud_network = models.ForeignKey(
209
+ to="cloud.CloudNetwork",
210
+ on_delete=models.PROTECT,
211
+ related_name="circuit_terminations",
212
+ blank=True,
213
+ null=True,
214
+ )
208
215
  port_speed = models.PositiveIntegerField(verbose_name="Port speed (Kbps)", blank=True, null=True)
209
216
  upstream_speed = models.PositiveIntegerField(
210
217
  blank=True,
@@ -221,16 +228,22 @@ class CircuitTermination(PrimaryModel, PathEndpoint, CableTermination):
221
228
  unique_together = ["circuit", "term_side"]
222
229
 
223
230
  def __str__(self):
224
- return f"Termination {self.term_side}: {self.location or self.provider_network}"
231
+ return f"Termination {self.term_side}: {self.location or self.provider_network or self.cloud_network}"
225
232
 
226
233
  def clean(self):
227
234
  super().clean()
228
235
 
229
236
  # Must define either location *or* provider network
230
- if self.location is None and self.provider_network is None:
231
- raise ValidationError("A circuit termination must attach to either a location or a provider network.")
237
+ if self.location is None and self.provider_network is None and self.cloud_network is None:
238
+ raise ValidationError(
239
+ "A circuit termination must attach to a location, a provider network or a cloud network."
240
+ )
232
241
  if self.location and self.provider_network:
233
242
  raise ValidationError("A circuit termination cannot attach to both a location and a provider network.")
243
+ elif self.location and self.cloud_network:
244
+ raise ValidationError("A circuit termination cannot attach to both a location and a cloud network.")
245
+ elif self.provider_network and self.cloud_network:
246
+ raise ValidationError("A circuit termination cannot attach to both a provider network and a cloud network.")
234
247
  # A valid location for contenttype CircuitTermination must be assigned.
235
248
  if self.location is not None:
236
249
  if ContentType.objects.get_for_model(self) not in self.location.location_type.content_types.all():
@@ -4,6 +4,7 @@ from django_tables2.utils import Accessor
4
4
  from nautobot.core.tables import (
5
5
  BaseTable,
6
6
  ButtonsColumn,
7
+ LinkedCountColumn,
7
8
  TagColumn,
8
9
  ToggleColumn,
9
10
  )
@@ -18,6 +19,8 @@ CIRCUIT_TERMINATION_PARENT = """
18
19
  {{ value.provider_network|hyperlinked_object }}
19
20
  {% elif value.location %}
20
21
  {{ value.location|hyperlinked_object }}
22
+ {% elif value.cloud_network %}
23
+ {{ value.cloud_network|hyperlinked_object }}
21
24
  {% else %}
22
25
  {{ None|placeholder }}
23
26
  {% endif %}
@@ -48,7 +51,11 @@ class ProviderNetworkTable(BaseTable):
48
51
  class ProviderTable(BaseTable):
49
52
  pk = ToggleColumn()
50
53
  name = tables.LinkColumn()
51
- circuit_count = tables.Column(accessor=Accessor("count_circuits"), verbose_name="Circuits")
54
+ circuit_count = LinkedCountColumn(
55
+ viewname="circuits:circuit_list",
56
+ url_params={"provider": "pk"},
57
+ verbose_name="Circuits",
58
+ )
52
59
  tags = TagColumn(url_name="circuits:provider_list")
53
60
 
54
61
  class Meta(BaseTable.Meta):
@@ -75,7 +82,11 @@ class ProviderTable(BaseTable):
75
82
  class CircuitTypeTable(BaseTable):
76
83
  pk = ToggleColumn()
77
84
  name = tables.LinkColumn()
78
- circuit_count = tables.Column(verbose_name="Circuits")
85
+ circuit_count = LinkedCountColumn(
86
+ viewname="circuits:circuit_list",
87
+ url_params={"circuit_type": "pk"},
88
+ verbose_name="Circuits",
89
+ )
79
90
  actions = ButtonsColumn(CircuitType)
80
91
 
81
92
  class Meta(BaseTable.Meta):
@@ -155,6 +166,7 @@ class CircuitTerminationTable(BaseTable):
155
166
  term_side = tables.Column(linkify=True)
156
167
  location = tables.Column(linkify=True)
157
168
  provider_network = tables.Column(linkify=True)
169
+ cloud_network = tables.Column(linkify=True)
158
170
  cable = tables.Column(linkify=True)
159
171
 
160
172
  class Meta(BaseTable.Meta):
@@ -165,6 +177,7 @@ class CircuitTerminationTable(BaseTable):
165
177
  "term_side",
166
178
  "location",
167
179
  "provider_network",
180
+ "cloud_network",
168
181
  "cable",
169
182
  "port_speed",
170
183
  "upstream_speed",
@@ -179,4 +192,5 @@ class CircuitTerminationTable(BaseTable):
179
192
  "term_side",
180
193
  "location",
181
194
  "provider_network",
195
+ "cloud_network",
182
196
  )
@@ -25,20 +25,28 @@
25
25
  <p class="form-control-static">{{ form.term_side.value }}</p>
26
26
  </div>
27
27
  </div>
28
+ {% with location_tab_active=form.initial.location %}
28
29
  {% with providernetwork_tab_active=form.initial.provider_network %}
30
+ {% with cloudnetwork_tab_active=form.initial.cloud_network %}
29
31
  <ul class="nav nav-tabs" role="tablist">
30
- <li role="presentation"{% if not providernetwork_tab_active %} class="active"{% endif %}><a href="#location" role="tab" data-toggle="tab">Location</a></li>
32
+ <li role="presentation"{% if location_tab_active or not providernetwork_tab_active and not cloudnetwork_tab_active %} class="active"{% endif %}><a href="#location" role="tab" data-toggle="tab">Location</a></li>
31
33
  <li role="presentation"{% if providernetwork_tab_active %} class="active"{% endif %}><a href="#providernetwork" role="tab" data-toggle="tab">Provider Network</a></li>
34
+ <li role="presentation"{% if cloudnetwork_tab_active %} class="active"{% endif %}><a href="#cloudnetwork" role="tab" data-toggle="tab">Cloud Network</a></li>
32
35
  </ul>
33
36
  <div class="tab-content">
34
- <div class="tab-pane{% if not providernetwork_tab_active %} active{% endif %}" id="location">
37
+ <div class="tab-pane{% if location_tab_active or not providernetwork_tab_active and not cloudnetwork_tab_active %} active{% endif %}" id="location">
35
38
  {% render_field form.location %}
36
39
  </div>
37
40
  <div class="tab-pane{% if providernetwork_tab_active %} active{% endif %}" id="providernetwork">
38
41
  {% render_field form.provider_network %}
39
42
  </div>
43
+ <div class="tab-pane{% if cloudnetwork_tab_active %} active{% endif %}" id="cloudnetwork">
44
+ {% render_field form.cloud_network %}
45
+ </div>
40
46
  </div>
41
47
  {% endwith %}
48
+ {% endwith %}
49
+ {% endwith %}
42
50
  </div>
43
51
  </div>
44
52
  <div class="panel panel-default">
@@ -24,6 +24,12 @@
24
24
  {{ object.provider_network|hyperlinked_object }}
25
25
  </td>
26
26
  {% endif %}
27
+ {% if object.cloud_network %}
28
+ <td>Cloud Network</td>
29
+ <td>
30
+ {{ object.cloud_network|hyperlinked_object }}
31
+ </td>
32
+ {% endif %}
27
33
  </tr>
28
34
  {% if object.location %}
29
35
  <tr>
@@ -82,11 +82,16 @@
82
82
  {% endif %}
83
83
  </td>
84
84
  </tr>
85
- {% else %}
85
+ {% elif termination.provider_network %}
86
86
  <tr>
87
87
  <td>Provider Network</td>
88
88
  <td>{{ termination.provider_network|hyperlinked_object }}</td>
89
89
  </tr>
90
+ {% else %}
91
+ <tr>
92
+ <td>Cloud Network</td>
93
+ <td>{{ termination.cloud_network|hyperlinked_object }}</td>
94
+ </tr>
90
95
  {% endif %}
91
96
  <tr>
92
97
  <td>Speed</td>
@@ -28,7 +28,9 @@ class ProviderTest(APIViewTestCases.APIViewTestCase):
28
28
  {
29
29
  "name": "Provider 6",
30
30
  },
31
- {"name": "Provider 7"},
31
+ {
32
+ "name": "Provider 7",
33
+ },
32
34
  ]
33
35
  bulk_update_data = {
34
36
  "asn": 1234,
@@ -250,12 +252,12 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
250
252
  circuits[0].circuit_termination_a.get_absolute_url(api=True),
251
253
  **self.header,
252
254
  )
253
- self.assertEqual(response.status_code, 200)
255
+ self.assertEqual(response.status_code, 200, response.json())
254
256
  response = self.client.get(
255
257
  circuits[0].circuit_termination_z.get_absolute_url(api=True),
256
258
  **self.header,
257
259
  )
258
- self.assertEqual(response.status_code, 200)
260
+ self.assertEqual(response.status_code, 200, response.json())
259
261
 
260
262
  with self.subTest("Assert CircuitTermination Cable connected to a FrontPort and CircuitTermination"):
261
263
  Cable.objects.create(
@@ -275,9 +277,9 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
275
277
  circuits[2].circuit_termination_a.get_absolute_url(api=True),
276
278
  **self.header,
277
279
  )
278
- self.assertEqual(response.status_code, 200)
280
+ self.assertEqual(response.status_code, 200, response.json())
279
281
  response = self.client.get(
280
282
  circuits[2].circuit_termination_z.get_absolute_url(api=True),
281
283
  **self.header,
282
284
  )
283
- self.assertEqual(response.status_code, 200)
285
+ self.assertEqual(response.status_code, 200, response.json())
@@ -89,6 +89,8 @@ class CircuitTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFil
89
89
  ["provider", "provider__name"],
90
90
  ["provider_network", "circuit_terminations__provider_network__id"],
91
91
  ["provider_network", "circuit_terminations__provider_network__name"],
92
+ ["cloud_network", "circuit_terminations__cloud_network__id"],
93
+ ["cloud_network", "circuit_terminations__cloud_network__name"],
92
94
  ["circuit_type", "circuit_type__id"],
93
95
  ["circuit_type", "circuit_type__name"],
94
96
  ["status", "status__id"],
@@ -108,7 +110,9 @@ class CircuitTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFil
108
110
  has_location=True,
109
111
  location=locations[1],
110
112
  )
111
- expected = self.queryset.filter(circuit_terminations__location__in=[locations[0].pk, locations[1].pk])
113
+ expected = self.queryset.filter(
114
+ circuit_terminations__location__in=[locations[0].pk, locations[1].pk]
115
+ ).distinct()
112
116
  params = {"location": [locations[0].pk, locations[1].pk]}
113
117
  self.assertQuerysetEqualAndNotEmpty(self.filterset(params, self.queryset).qs, expected)
114
118
  params = {"location": [locations[0].name, locations[1].name]}
@@ -127,6 +131,8 @@ class CircuitTerminationTestCase(FilterTestCases.FilterTestCase):
127
131
  generic_filter_tests = (
128
132
  ["circuit", "circuit__cid"],
129
133
  ["circuit", "circuit__id"],
134
+ ["cloud_network", "cloud_network__name"],
135
+ ["cloud_network", "cloud_network__id"],
130
136
  ["description"],
131
137
  ["port_speed"],
132
138
  ["pp_info"],
@@ -157,7 +163,8 @@ class CircuitTerminationTestCase(FilterTestCases.FilterTestCase):
157
163
  location=location,
158
164
  )
159
165
  interface_status = Status.objects.get_for_model(Interface).first()
160
- interface1 = Interface.objects.create(device=device1, name="eth0", status=interface_status)
166
+ interface_role = Role.objects.get_for_model(Interface).first()
167
+ interface1 = Interface.objects.create(device=device1, name="eth0", status=interface_status, role=interface_role)
161
168
  interface2 = Interface.objects.create(device=device2, name="eth0", status=interface_status)
162
169
 
163
170
  circuit_terminations = CircuitTermination.objects.all()
@@ -182,17 +189,17 @@ class CircuitTerminationTestCase(FilterTestCases.FilterTestCase):
182
189
  with self.subTest(f"term_side: {choice}"):
183
190
  params = {"term_side": [choice]}
184
191
  filterset_result = self.filterset(params, self.queryset).qs
185
- qs_result = self.queryset.filter(term_side=choice)
192
+ qs_result = self.queryset.filter(term_side=choice).distinct()
186
193
  self.assertQuerysetEqualAndNotEmpty(filterset_result, qs_result)
187
194
 
188
195
  def test_connected(self):
189
196
  params = {"connected": True}
190
197
  filterset_result = self.filterset(params, self.queryset).qs
191
- qs_result = self.queryset.filter(_path__is_active=True)
198
+ qs_result = self.queryset.filter(_path__is_active=True).distinct()
192
199
  self.assertQuerysetEqualAndNotEmpty(filterset_result, qs_result)
193
200
  params = {"connected": False}
194
201
  filterset_result = self.filterset(params, self.queryset).qs
195
- qs_result = self.queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
202
+ qs_result = self.queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False)).distinct()
196
203
  self.assertQuerysetEqualAndNotEmpty(filterset_result, qs_result)
197
204
 
198
205
 
@@ -3,6 +3,7 @@ from django.core.exceptions import ValidationError
3
3
 
4
4
  from nautobot.circuits.choices import CircuitTerminationSideChoices
5
5
  from nautobot.circuits.models import Circuit, CircuitTermination, CircuitType, Provider, ProviderNetwork
6
+ from nautobot.cloud.models import CloudAccount, CloudNetwork, CloudResourceType
6
7
  from nautobot.core.testing.models import ModelTestCases
7
8
  from nautobot.dcim.models import Location, LocationType
8
9
  from nautobot.extras.models import Status
@@ -28,11 +29,19 @@ class CircuitTerminationModelTestCase(ModelTestCases.BaseModelTestCase):
28
29
  cls.location_1 = Location.objects.filter(location_type=location_type_1)[0]
29
30
  cls.location_2 = Location.objects.filter(location_type=location_type_2)[0]
30
31
 
31
- def test_location_or_provider_network_are_required(self):
32
+ cloud_resource_type = CloudResourceType.objects.get_for_model(CloudNetwork).first()
33
+ cloud_account = CloudAccount.objects.filter(provider=cloud_resource_type.provider).first()
34
+ cls.cloud_network = CloudNetwork(
35
+ cloud_account=cloud_account,
36
+ cloud_resource_type=cloud_resource_type,
37
+ name="Cloud Network 1",
38
+ )
39
+
40
+ def test_location_or_provider_network_or_cloud_network_are_required(self):
32
41
  ct = CircuitTermination(circuit=self.circuit, term_side=CircuitTerminationSideChoices.SIDE_A)
33
42
  with self.assertRaises(ValidationError) as cm:
34
43
  ct.validated_save()
35
- self.assertIn("must attach to either a location or a provider network", str(cm.exception))
44
+ self.assertIn("must attach to a location, a provider network or a cloud network", str(cm.exception))
36
45
 
37
46
  def test_location_and_provider_network_mutually_exclusive(self):
38
47
  ct = CircuitTermination(
@@ -45,6 +54,28 @@ class CircuitTerminationModelTestCase(ModelTestCases.BaseModelTestCase):
45
54
  ct.validated_save()
46
55
  self.assertIn("cannot attach to both a location and a provider network", str(cm.exception))
47
56
 
57
+ def test_location_and_cloud_network_mutually_exclusive(self):
58
+ ct = CircuitTermination(
59
+ circuit=self.circuit,
60
+ term_side=CircuitTerminationSideChoices.SIDE_A,
61
+ cloud_network=self.cloud_network,
62
+ location=self.location_2,
63
+ )
64
+ with self.assertRaises(ValidationError) as cm:
65
+ ct.validated_save()
66
+ self.assertIn("cannot attach to both a location and a cloud network", str(cm.exception))
67
+
68
+ def test_provider_network_and_cloud_network_mutually_exclusive(self):
69
+ ct = CircuitTermination(
70
+ circuit=self.circuit,
71
+ term_side=CircuitTerminationSideChoices.SIDE_A,
72
+ cloud_network=self.cloud_network,
73
+ provider_network=self.provider_network,
74
+ )
75
+ with self.assertRaises(ValidationError) as cm:
76
+ ct.validated_save()
77
+ self.assertIn("cannot attach to both a provider network and a cloud network", str(cm.exception))
78
+
48
79
  def test_location_content_type_enforced(self):
49
80
  ct = CircuitTermination(
50
81
  circuit=self.circuit,
@@ -5,7 +5,6 @@ from django.shortcuts import get_object_or_404, redirect, render
5
5
  from django_tables2 import RequestConfig
6
6
 
7
7
  from nautobot.core.forms import ConfirmationForm
8
- from nautobot.core.models.querysets import count_related
9
8
  from nautobot.core.views import generic, mixins as view_mixins
10
9
  from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
11
10
  from nautobot.core.views.viewsets import NautobotUIViewSet
@@ -29,7 +28,7 @@ class CircuitTypeUIViewSet(
29
28
  filterset_class = filters.CircuitTypeFilterSet
30
29
  filterset_form_class = forms.CircuitTypeFilterForm
31
30
  form_class = forms.CircuitTypeForm
32
- queryset = CircuitType.objects.annotate(circuit_count=count_related(Circuit, "circuit_type"))
31
+ queryset = CircuitType.objects.all()
33
32
  serializer_class = serializers.CircuitTypeSerializer
34
33
  table_class = tables.CircuitTypeTable
35
34
 
@@ -92,7 +91,7 @@ class ProviderUIViewSet(NautobotUIViewSet):
92
91
  filterset_class = filters.ProviderFilterSet
93
92
  filterset_form_class = forms.ProviderFilterForm
94
93
  form_class = forms.ProviderForm
95
- queryset = Provider.objects.annotate(count_circuits=count_related(Circuit, "provider"))
94
+ queryset = Provider.objects.all()
96
95
  serializer_class = serializers.ProviderSerializer
97
96
  table_class = tables.ProviderTable
98
97
 
File without changes
File without changes