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