nautobot 2.2.8__py3-none-any.whl → 2.3.0__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 (704) 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 +113 -0
  26. nautobot/cloud/filters.py +187 -0
  27. nautobot/cloud/forms.py +339 -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 +246 -0
  32. nautobot/cloud/navigation.py +85 -0
  33. nautobot/cloud/tables.py +157 -0
  34. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +43 -0
  35. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +122 -0
  36. nautobot/cloud/templates/cloud/cloudnetwork_update.html +33 -0
  37. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +111 -0
  38. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +69 -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 +125 -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 +110 -14
  57. nautobot/core/forms/fields.py +10 -4
  58. nautobot/core/forms/forms.py +11 -3
  59. nautobot/core/forms/widgets.py +18 -1
  60. nautobot/core/graphql/generators.py +2 -2
  61. nautobot/core/graphql/schema.py +28 -7
  62. nautobot/core/jobs/__init__.py +20 -3
  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 +15 -19
  73. nautobot/core/settings.yaml +48 -13
  74. nautobot/core/settings_funcs.py +103 -0
  75. nautobot/core/tables.py +130 -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 +28 -8
  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 +63 -14
  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 +204 -2
  120. nautobot/core/tests/test_tables.py +3 -1
  121. nautobot/core/tests/test_templatetags_helpers.py +12 -5
  122. nautobot/core/tests/test_templatetags_netutils.py +3 -3
  123. nautobot/core/tests/test_utils.py +31 -20
  124. nautobot/core/tests/test_views.py +6 -6
  125. nautobot/core/urls.py +8 -3
  126. nautobot/core/utils/deprecation.py +29 -0
  127. nautobot/core/utils/filtering.py +12 -9
  128. nautobot/core/utils/lookup.py +37 -2
  129. nautobot/core/utils/requests.py +4 -1
  130. nautobot/core/views/__init__.py +137 -24
  131. nautobot/core/views/generic.py +119 -67
  132. nautobot/core/views/mixins.py +105 -36
  133. nautobot/core/views/paginator.py +9 -3
  134. nautobot/core/views/renderers.py +121 -56
  135. nautobot/core/views/utils.py +81 -1
  136. nautobot/dcim/__init__.py +0 -1
  137. nautobot/dcim/api/serializers.py +180 -44
  138. nautobot/dcim/api/urls.py +7 -3
  139. nautobot/dcim/api/views.py +53 -7
  140. nautobot/dcim/apps.py +3 -0
  141. nautobot/dcim/choices.py +25 -0
  142. nautobot/dcim/constants.py +7 -0
  143. nautobot/dcim/factory.py +252 -18
  144. nautobot/dcim/filters/__init__.py +373 -193
  145. nautobot/dcim/filters/mixins.py +274 -1
  146. nautobot/dcim/forms.py +834 -121
  147. nautobot/dcim/graphql/types.py +2 -2
  148. nautobot/dcim/homepage.py +1 -1
  149. nautobot/dcim/migrations/0059_add_role_field_to_interface_models.py +27 -0
  150. nautobot/dcim/migrations/0060_alter_cable_status_alter_consoleport__path_and_more.py +303 -0
  151. nautobot/dcim/migrations/0061_module_models.py +862 -0
  152. nautobot/dcim/migrations/0062_module_data_migration.py +25 -0
  153. nautobot/dcim/models/__init__.py +8 -0
  154. nautobot/dcim/models/cables.py +15 -0
  155. nautobot/dcim/models/device_component_templates.py +207 -53
  156. nautobot/dcim/models/device_components.py +282 -99
  157. nautobot/dcim/models/devices.py +472 -13
  158. nautobot/dcim/models/racks.py +0 -1
  159. nautobot/dcim/navigation.py +47 -0
  160. nautobot/dcim/signals.py +3 -3
  161. nautobot/dcim/tables/__init__.py +35 -23
  162. nautobot/dcim/tables/devices.py +248 -47
  163. nautobot/dcim/tables/devicetypes.py +65 -9
  164. nautobot/dcim/tables/racks.py +5 -1
  165. nautobot/dcim/tables/template_code.py +46 -26
  166. nautobot/dcim/templates/dcim/cable_connect.html +76 -3
  167. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -5
  168. nautobot/dcim/templates/dcim/device/base.html +14 -6
  169. nautobot/dcim/templates/dcim/device/consoleports.html +2 -3
  170. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -3
  171. nautobot/dcim/templates/dcim/device/devicebays.html +6 -7
  172. nautobot/dcim/templates/dcim/device/frontports.html +2 -3
  173. nautobot/dcim/templates/dcim/device/interfaces.html +2 -3
  174. nautobot/dcim/templates/dcim/device/inventory.html +2 -3
  175. nautobot/dcim/templates/dcim/device/modulebays.html +49 -0
  176. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -3
  177. nautobot/dcim/templates/dcim/device/powerports.html +2 -3
  178. nautobot/dcim/templates/dcim/device/rearports.html +2 -3
  179. nautobot/dcim/templates/dcim/device.html +45 -1
  180. nautobot/dcim/templates/dcim/device_component.html +13 -5
  181. nautobot/dcim/templates/dcim/device_list.html +2 -1
  182. nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +6 -0
  183. nautobot/dcim/templates/dcim/devicetype.html +99 -98
  184. nautobot/dcim/templates/dcim/devicetype_list.html +8 -16
  185. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  186. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +39 -0
  187. nautobot/dcim/templates/dcim/interface.html +17 -2
  188. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -5
  189. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  190. nautobot/dcim/templates/dcim/manufacturer.html +24 -0
  191. nautobot/dcim/templates/dcim/module/base.html +97 -0
  192. nautobot/dcim/templates/dcim/module_bulk_destroy.html +5 -0
  193. nautobot/dcim/templates/dcim/module_consoleports.html +53 -0
  194. nautobot/dcim/templates/dcim/module_consoleserverports.html +53 -0
  195. nautobot/dcim/templates/dcim/module_destroy.html +5 -0
  196. nautobot/dcim/templates/dcim/module_frontports.html +53 -0
  197. nautobot/dcim/templates/dcim/module_interfaces.html +57 -0
  198. nautobot/dcim/templates/dcim/module_list.html +20 -0
  199. nautobot/dcim/templates/dcim/module_modulebays.html +49 -0
  200. nautobot/dcim/templates/dcim/module_poweroutlets.html +53 -0
  201. nautobot/dcim/templates/dcim/module_powerports.html +53 -0
  202. nautobot/dcim/templates/dcim/module_rearports.html +53 -0
  203. nautobot/dcim/templates/dcim/module_retrieve.html +63 -0
  204. nautobot/dcim/templates/dcim/module_update.html +71 -0
  205. nautobot/dcim/templates/dcim/modulebay_bulk_destroy.html +5 -0
  206. nautobot/dcim/templates/dcim/modulebay_destroy.html +8 -0
  207. nautobot/dcim/templates/dcim/modulebay_retrieve.html +101 -0
  208. nautobot/dcim/templates/dcim/moduletype_list.html +11 -0
  209. nautobot/dcim/templates/dcim/moduletype_retrieve.html +159 -0
  210. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -5
  211. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +65 -19
  212. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  213. nautobot/dcim/tests/test_api.py +693 -208
  214. nautobot/dcim/tests/test_filters.py +843 -217
  215. nautobot/dcim/tests/test_models.py +1103 -8
  216. nautobot/dcim/tests/test_views.py +1525 -343
  217. nautobot/dcim/urls.py +17 -2
  218. nautobot/dcim/utils.py +2 -3
  219. nautobot/dcim/views.py +1109 -113
  220. nautobot/extras/__init__.py +0 -1
  221. nautobot/extras/api/serializers.py +115 -3
  222. nautobot/extras/api/urls.py +12 -0
  223. nautobot/extras/api/views.py +73 -59
  224. nautobot/extras/apps.py +2 -2
  225. nautobot/extras/choices.py +43 -0
  226. nautobot/extras/context_managers.py +13 -8
  227. nautobot/extras/datasources/git.py +2 -0
  228. nautobot/extras/factory.py +460 -9
  229. nautobot/extras/filters/__init__.py +174 -3
  230. nautobot/extras/filters/mixins.py +46 -43
  231. nautobot/extras/forms/base.py +24 -5
  232. nautobot/extras/forms/forms.py +227 -8
  233. nautobot/extras/forms/mixins.py +93 -0
  234. nautobot/extras/graphql/types.py +23 -10
  235. nautobot/extras/homepage.py +26 -3
  236. nautobot/extras/jobs.py +2 -2
  237. nautobot/extras/management/__init__.py +1 -0
  238. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -16
  239. nautobot/extras/migrations/0021_customfield_changelog_data.py +1 -0
  240. nautobot/extras/migrations/0109_dynamicgroup_group_type_dynamicgroup_tags_and_more.py +108 -0
  241. nautobot/extras/migrations/0110_alter_configcontext_cluster_groups_and_more.py +111 -0
  242. nautobot/extras/migrations/0111_metadata.py +162 -0
  243. nautobot/extras/migrations/0112_dynamic_group_group_type_data_migration.py +28 -0
  244. nautobot/extras/migrations/0113_saved_views.py +77 -0
  245. nautobot/extras/models/__init__.py +15 -1
  246. nautobot/extras/models/change_logging.py +3 -3
  247. nautobot/extras/models/contacts.py +4 -0
  248. nautobot/extras/models/customfields.py +18 -3
  249. nautobot/extras/models/groups.py +389 -225
  250. nautobot/extras/models/jobs.py +87 -3
  251. nautobot/extras/models/metadata.py +441 -0
  252. nautobot/extras/models/mixins.py +72 -62
  253. nautobot/extras/models/models.py +118 -9
  254. nautobot/extras/models/relationships.py +9 -2
  255. nautobot/extras/models/tags.py +13 -2
  256. nautobot/extras/navigation.py +57 -0
  257. nautobot/extras/plugins/__init__.py +3 -1
  258. nautobot/extras/querysets.py +30 -66
  259. nautobot/extras/signals.py +109 -101
  260. nautobot/extras/tables.py +201 -17
  261. nautobot/extras/templates/extras/dynamicgroup.html +44 -15
  262. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -0
  263. nautobot/extras/templates/extras/job.html +1 -1
  264. nautobot/extras/templates/extras/job_detail.html +11 -0
  265. nautobot/extras/templates/extras/jobresult.html +61 -74
  266. nautobot/extras/templates/extras/metadatatype_create.html +89 -0
  267. nautobot/extras/templates/extras/metadatatype_retrieve.html +67 -0
  268. nautobot/extras/templates/extras/object_dynamicgroups.html +7 -0
  269. nautobot/extras/templates/extras/objectchange_list.html +0 -12
  270. nautobot/extras/templates/extras/plugins_list.html +1 -3
  271. nautobot/extras/templates/extras/role_retrieve.html +48 -0
  272. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +20 -0
  273. nautobot/extras/tests/integration/test_customfields.py +1 -0
  274. nautobot/extras/tests/test_api.py +509 -23
  275. nautobot/extras/tests/test_changelog.py +20 -9
  276. nautobot/extras/tests/test_context_managers.py +22 -15
  277. nautobot/extras/tests/test_datasources.py +13 -1
  278. nautobot/extras/tests/test_dynamicgroups.py +201 -171
  279. nautobot/extras/tests/test_filters.py +211 -12
  280. nautobot/extras/tests/test_jobs.py +6 -6
  281. nautobot/extras/tests/test_models.py +501 -4
  282. nautobot/extras/tests/test_relationships.py +1 -0
  283. nautobot/extras/tests/test_views.py +586 -8
  284. nautobot/extras/tests/test_webhooks.py +1 -1
  285. nautobot/extras/urls.py +5 -0
  286. nautobot/extras/utils.py +85 -16
  287. nautobot/extras/views.py +562 -122
  288. nautobot/ipam/__init__.py +0 -1
  289. nautobot/ipam/apps.py +1 -0
  290. nautobot/ipam/factory.py +17 -19
  291. nautobot/ipam/filters.py +13 -0
  292. nautobot/ipam/forms.py +8 -4
  293. nautobot/ipam/graphql/types.py +2 -2
  294. nautobot/ipam/migrations/0047_alter_ipaddress_role_alter_ipaddress_status_and_more.py +59 -0
  295. nautobot/ipam/models.py +20 -20
  296. nautobot/ipam/querysets.py +1 -1
  297. nautobot/ipam/signals.py +4 -2
  298. nautobot/ipam/tables.py +5 -0
  299. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +1 -1
  300. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +1 -1
  301. nautobot/ipam/templates/ipam/prefix.html +1 -0
  302. nautobot/ipam/tests/test_api.py +37 -18
  303. nautobot/ipam/tests/test_filters.py +26 -2
  304. nautobot/ipam/tests/test_models.py +9 -2
  305. nautobot/ipam/tests/test_querysets.py +1 -1
  306. nautobot/ipam/tests/test_views.py +3 -2
  307. nautobot/ipam/urls.py +2 -2
  308. nautobot/ipam/views.py +20 -34
  309. nautobot/project-static/css/base.css +21 -0
  310. nautobot/project-static/css/dark.css +11 -0
  311. nautobot/project-static/docs/404.html +894 -90
  312. nautobot/project-static/docs/apps/index.html +894 -90
  313. nautobot/project-static/docs/apps/nautobot-apps.html +894 -90
  314. nautobot/project-static/docs/assets/_mkdocstrings.css +5 -0
  315. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +1 -0
  316. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +1 -0
  317. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +921 -122
  318. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +906 -103
  319. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1620 -905
  320. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +937 -146
  321. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +979 -190
  322. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +903 -101
  323. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +899 -95
  324. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +993 -195
  325. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +976 -133
  326. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1080 -274
  327. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1244 -336
  328. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1729 -877
  329. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1166 -383
  330. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2090 -1376
  331. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2248 -1424
  332. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +914 -113
  333. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +965 -165
  334. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1012 -225
  335. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +1915 -1279
  336. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1848 -1104
  337. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +906 -103
  338. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2335 -1701
  339. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1804 -1026
  340. nautobot/project-static/docs/development/apps/api/configuration-view.html +894 -90
  341. nautobot/project-static/docs/development/apps/api/database-backend-config.html +894 -90
  342. nautobot/project-static/docs/development/apps/api/models/django-admin.html +894 -90
  343. nautobot/project-static/docs/development/apps/api/models/global-search.html +894 -90
  344. nautobot/project-static/docs/development/apps/api/models/graphql.html +894 -90
  345. nautobot/project-static/docs/development/apps/api/models/index.html +944 -92
  346. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +894 -90
  347. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +894 -90
  348. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +894 -90
  349. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +894 -90
  350. nautobot/project-static/docs/development/apps/api/platform-features/index.html +894 -90
  351. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +894 -90
  352. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +894 -90
  353. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +894 -90
  354. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +894 -90
  355. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +894 -90
  356. nautobot/project-static/docs/development/apps/api/prometheus.html +894 -90
  357. nautobot/project-static/docs/development/apps/api/setup.html +894 -90
  358. nautobot/project-static/docs/development/apps/api/testing.html +894 -90
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +894 -90
  360. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +894 -90
  361. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +894 -90
  362. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +894 -90
  363. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +894 -90
  364. nautobot/project-static/docs/development/apps/api/views/base-template.html +894 -90
  365. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +894 -90
  366. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +894 -90
  367. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +894 -90
  368. nautobot/project-static/docs/development/apps/api/views/index.html +894 -90
  369. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +894 -90
  370. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +894 -90
  371. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +894 -90
  372. nautobot/project-static/docs/development/apps/api/views/notes.html +894 -90
  373. nautobot/project-static/docs/development/apps/api/views/rest-api.html +894 -90
  374. nautobot/project-static/docs/development/apps/api/views/urls.html +894 -90
  375. nautobot/project-static/docs/development/apps/index.html +894 -90
  376. nautobot/project-static/docs/development/apps/migration/code-updates.html +894 -90
  377. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +894 -90
  378. nautobot/project-static/docs/development/apps/migration/from-v1.html +894 -90
  379. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +894 -90
  380. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +894 -90
  381. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +894 -90
  382. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +894 -90
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +894 -90
  384. nautobot/project-static/docs/development/core/application-registry.html +894 -90
  385. nautobot/project-static/docs/development/core/best-practices.html +895 -90
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +894 -90
  387. nautobot/project-static/docs/development/core/caching.html +894 -90
  388. nautobot/project-static/docs/development/core/controllers.html +894 -90
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +894 -90
  390. nautobot/project-static/docs/development/core/generic-views.html +894 -90
  391. nautobot/project-static/docs/development/core/getting-started.html +894 -90
  392. nautobot/project-static/docs/development/core/homepage.html +894 -90
  393. nautobot/project-static/docs/development/core/index.html +905 -90
  394. nautobot/project-static/docs/development/core/model-checklist.html +903 -91
  395. nautobot/project-static/docs/development/core/model-features.html +894 -90
  396. nautobot/project-static/docs/development/core/natural-keys.html +894 -90
  397. nautobot/project-static/docs/development/core/navigation-menu.html +894 -90
  398. nautobot/project-static/docs/development/core/release-checklist.html +897 -93
  399. nautobot/project-static/docs/development/core/role-internals.html +894 -90
  400. nautobot/project-static/docs/development/core/settings.html +894 -90
  401. nautobot/project-static/docs/development/core/style-guide.html +895 -91
  402. nautobot/project-static/docs/development/core/templates.html +906 -91
  403. nautobot/project-static/docs/development/core/testing.html +894 -90
  404. nautobot/project-static/docs/development/core/user-preferences.html +894 -90
  405. nautobot/project-static/docs/development/index.html +894 -90
  406. nautobot/project-static/docs/development/jobs/index.html +1271 -453
  407. nautobot/project-static/docs/development/jobs/migration/from-v1.html +894 -90
  408. nautobot/project-static/docs/index.html +9032 -13
  409. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_dark.png +0 -0
  410. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_light.png +0 -0
  411. nautobot/project-static/docs/models/cloud/cloudaccount.html +15 -0
  412. nautobot/project-static/docs/models/cloud/cloudnetwork.html +15 -0
  413. nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +15 -0
  414. nautobot/project-static/docs/models/cloud/cloudresourcetype.html +15 -0
  415. nautobot/project-static/docs/models/cloud/cloudservice.html +15 -0
  416. nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +15 -0
  417. nautobot/project-static/docs/models/dcim/module.html +15 -0
  418. nautobot/project-static/docs/models/dcim/modulebay.html +15 -0
  419. nautobot/project-static/docs/models/dcim/modulebaytemplate.html +15 -0
  420. nautobot/project-static/docs/models/dcim/moduletype.html +15 -0
  421. nautobot/project-static/docs/models/extras/metadatachoice.html +15 -0
  422. nautobot/project-static/docs/models/extras/metadatatype.html +15 -0
  423. nautobot/project-static/docs/models/extras/objectmetadata.html +15 -0
  424. nautobot/project-static/docs/models/extras/role.html +15 -0
  425. nautobot/project-static/docs/models/extras/savedview.html +15 -0
  426. nautobot/project-static/docs/models/extras/staticgroupassociation.html +15 -0
  427. nautobot/project-static/docs/models/extras/status.html +15 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +902 -91
  430. nautobot/project-static/docs/overview/design_philosophy.html +896 -92
  431. nautobot/project-static/docs/overview/index.html +13 -8228
  432. nautobot/project-static/docs/release-notes/index.html +1131 -94
  433. nautobot/project-static/docs/release-notes/version-1.0.html +894 -90
  434. nautobot/project-static/docs/release-notes/version-1.1.html +894 -90
  435. nautobot/project-static/docs/release-notes/version-1.2.html +894 -90
  436. nautobot/project-static/docs/release-notes/version-1.3.html +894 -90
  437. nautobot/project-static/docs/release-notes/version-1.4.html +894 -90
  438. nautobot/project-static/docs/release-notes/version-1.5.html +895 -91
  439. nautobot/project-static/docs/release-notes/version-1.6.html +895 -91
  440. nautobot/project-static/docs/release-notes/version-2.0.html +894 -90
  441. nautobot/project-static/docs/release-notes/version-2.1.html +894 -90
  442. nautobot/project-static/docs/release-notes/version-2.2.html +1137 -196
  443. nautobot/project-static/docs/release-notes/version-2.3.html +9954 -0
  444. nautobot/project-static/docs/requirements.txt +5 -5
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +335 -260
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +894 -90
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +894 -90
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +894 -90
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +894 -90
  452. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +1025 -175
  453. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +894 -90
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +894 -90
  455. nautobot/project-static/docs/user-guide/administration/guides/caching.html +894 -90
  456. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +902 -90
  457. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +894 -90
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +894 -90
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +894 -90
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +894 -90
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +894 -90
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +894 -90
  463. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +894 -90
  464. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +894 -90
  465. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +946 -155
  466. nautobot/project-static/docs/user-guide/administration/installation/index.html +903 -95
  467. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +936 -124
  468. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +956 -159
  469. nautobot/project-static/docs/user-guide/administration/installation/services.html +915 -114
  470. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +910 -101
  471. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +894 -90
  472. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +894 -90
  473. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +894 -90
  474. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +894 -90
  475. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +977 -121
  476. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +894 -90
  477. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +894 -90
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +894 -90
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +894 -90
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +894 -90
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +894 -90
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +894 -90
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +894 -90
  484. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +894 -90
  485. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +894 -90
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +894 -90
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +895 -91
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +894 -90
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +898 -90
  490. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +897 -93
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +8984 -0
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +8828 -0
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +8829 -0
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +8828 -0
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +8829 -0
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +8833 -0
  497. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +8828 -0
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +908 -104
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +925 -107
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +925 -107
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +920 -102
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +925 -107
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +908 -104
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +908 -104
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +915 -107
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +922 -118
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +923 -119
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +920 -116
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +908 -104
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +916 -107
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +928 -110
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +938 -120
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +930 -108
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +908 -104
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +939 -121
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +930 -112
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +920 -116
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +923 -119
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +925 -117
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +8828 -0
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +8846 -0
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +8843 -0
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +8823 -0
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +918 -114
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +908 -104
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +942 -85
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +926 -108
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +908 -104
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +945 -88
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +923 -105
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +931 -127
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +920 -116
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +908 -104
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +924 -106
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +926 -108
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +908 -104
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +908 -104
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +908 -104
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +938 -90
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +894 -90
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +899 -91
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +899 -91
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +894 -90
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +894 -90
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +894 -90
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +894 -90
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +894 -90
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +894 -90
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +894 -90
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +894 -90
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +894 -90
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +894 -90
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +903 -98
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +894 -90
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +894 -90
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +894 -90
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +894 -90
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +894 -90
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +899 -91
  560. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +894 -90
  561. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +894 -90
  562. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +894 -90
  563. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +894 -90
  564. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +894 -90
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +894 -90
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +894 -90
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +894 -90
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +894 -90
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +894 -90
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +894 -90
  571. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +894 -90
  572. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +894 -90
  573. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/clear-view-button.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/cleared-view.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/config-table-columns-to-locations.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/configure-button.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/create-saved-view-success.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/current-saved-view-drop-down-menu.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/default-location-list-view.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/dropdown-button-after-new-saved-view.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-application-to-locations.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-button.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/global-default-location-list-view.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/location-list-view-with-saved-views.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/navigation-menu.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-as-new-view-drop-down.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-view-modal.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-buttons.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-success.png +0 -0
  590. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view-unchecked.png +0 -0
  591. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view.png +0 -0
  592. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-different-user.png +0 -0
  593. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-modal-unchecked.png +0 -0
  594. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-button.png +0 -0
  595. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-success.png +0 -0
  596. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/unsaved-saved-view.png +0 -0
  597. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/updated-saved-view.png +0 -0
  598. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +894 -90
  599. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +894 -90
  600. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +894 -90
  601. nautobot/project-static/docs/user-guide/index.html +894 -90
  602. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +894 -90
  603. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +894 -90
  604. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +894 -90
  605. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +894 -90
  606. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1260 -787
  607. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +897 -93
  608. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +894 -90
  609. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +894 -90
  610. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +894 -90
  611. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +894 -90
  612. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +894 -90
  613. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +894 -90
  614. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +894 -90
  615. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +894 -90
  616. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +894 -90
  617. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +898 -90
  618. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +894 -90
  619. nautobot/project-static/docs/user-guide/platform-functionality/note.html +897 -93
  620. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +9061 -0
  621. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +897 -93
  622. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +894 -90
  623. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +894 -90
  624. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +894 -90
  625. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +894 -90
  626. nautobot/project-static/docs/user-guide/platform-functionality/role.html +897 -93
  627. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9137 -0
  628. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +897 -93
  629. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +8933 -0
  630. nautobot/project-static/docs/user-guide/platform-functionality/status.html +894 -90
  631. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +894 -90
  632. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +952 -123
  633. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +894 -90
  634. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +894 -90
  635. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +894 -90
  636. nautobot/project-static/js/forms.js +71 -0
  637. nautobot/project-static/js/table_sorting_indicator.js +46 -0
  638. nautobot/project-static/js/tableconfig.js +6 -1
  639. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +3 -0
  640. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.eot +0 -0
  641. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.ttf +0 -0
  642. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff +0 -0
  643. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 +0 -0
  644. nautobot/tenancy/__init__.py +0 -1
  645. nautobot/tenancy/apps.py +1 -0
  646. nautobot/tenancy/factory.py +3 -2
  647. nautobot/tenancy/filters/__init__.py +1 -0
  648. nautobot/tenancy/forms.py +1 -1
  649. nautobot/tenancy/templates/tenancy/tenant.html +24 -20
  650. nautobot/tenancy/views.py +11 -10
  651. nautobot/users/__init__.py +0 -1
  652. nautobot/users/api/serializers.py +1 -1
  653. nautobot/users/api/views.py +4 -2
  654. nautobot/users/apps.py +3 -2
  655. nautobot/users/factory.py +3 -3
  656. nautobot/users/migrations/0010_user_default_saved_views.py +20 -0
  657. nautobot/users/models.py +12 -0
  658. nautobot/users/tests/test_filters.py +6 -3
  659. nautobot/users/urls.py +8 -0
  660. nautobot/virtualization/__init__.py +0 -1
  661. nautobot/virtualization/apps.py +1 -0
  662. nautobot/virtualization/filters.py +6 -1
  663. nautobot/virtualization/forms.py +11 -3
  664. nautobot/virtualization/graphql/types.py +2 -2
  665. nautobot/virtualization/migrations/0029_add_role_field_to_interface_models.py +27 -0
  666. nautobot/virtualization/migrations/0030_alter_virtualmachine_local_config_context_data_owner_content_type_and_more.py +67 -0
  667. nautobot/virtualization/models.py +0 -2
  668. nautobot/virtualization/tables.py +12 -8
  669. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  670. nautobot/virtualization/templates/virtualization/vminterface.html +7 -1
  671. nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
  672. nautobot/virtualization/tests/test_api.py +9 -4
  673. nautobot/virtualization/tests/test_filters.py +22 -0
  674. nautobot/virtualization/tests/test_models.py +7 -3
  675. nautobot/virtualization/tests/test_views.py +19 -3
  676. nautobot/virtualization/urls.py +2 -2
  677. nautobot/virtualization/views.py +10 -32
  678. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/METADATA +21 -19
  679. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/RECORD +684 -564
  680. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css +0 -1
  681. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css.map +0 -1
  682. nautobot/project-static/materialdesignicons-6.5.95/.github/ISSUE_TEMPLATE.md +0 -3
  683. nautobot/project-static/materialdesignicons-6.5.95/README.md +0 -25
  684. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css +0 -26654
  685. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css.map +0 -16
  686. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css +0 -3
  687. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css.map +0 -16
  688. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff +0 -0
  689. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff2 +0 -0
  690. nautobot/project-static/materialdesignicons-6.5.95/package.json +0 -28
  691. nautobot/project-static/materialdesignicons-6.5.95/preview.html +0 -717
  692. nautobot/project-static/materialdesignicons-6.5.95/scss/_animated.scss +0 -27
  693. nautobot/project-static/materialdesignicons-6.5.95/scss/_core.scss +0 -10
  694. nautobot/project-static/materialdesignicons-6.5.95/scss/_extras.scss +0 -65
  695. nautobot/project-static/materialdesignicons-6.5.95/scss/_functions.scss +0 -20
  696. nautobot/project-static/materialdesignicons-6.5.95/scss/_icons.scss +0 -10
  697. nautobot/project-static/materialdesignicons-6.5.95/scss/_path.scss +0 -10
  698. nautobot/project-static/materialdesignicons-6.5.95/scss/_variables.scss +0 -6606
  699. nautobot/project-static/materialdesignicons-6.5.95/scss/materialdesignicons.scss +0 -8
  700. /nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/LICENSE +0 -0
  701. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/LICENSE.txt +0 -0
  702. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/NOTICE +0 -0
  703. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/WHEEL +0 -0
  704. {nautobot-2.2.8.dist-info → nautobot-2.3.0.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