nautobot 2.4.21__py3-none-any.whl → 3.0.0a3__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 (919) hide show
  1. nautobot/apps/choices.py +2 -2
  2. nautobot/apps/filters.py +9 -9
  3. nautobot/apps/forms.py +2 -0
  4. nautobot/apps/models.py +7 -2
  5. nautobot/apps/ui.py +20 -1
  6. nautobot/apps/utils.py +2 -3
  7. nautobot/apps/views.py +7 -1
  8. nautobot/circuits/filters.py +8 -23
  9. nautobot/circuits/navigation.py +3 -1
  10. nautobot/circuits/templates/circuits/circuit_create.html +9 -9
  11. nautobot/circuits/templates/circuits/circuit_terminations_swap.html +2 -2
  12. nautobot/circuits/templates/circuits/circuittermination_create.html +24 -33
  13. nautobot/circuits/templates/circuits/inc/circuit_termination.html +10 -10
  14. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +13 -13
  15. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +6 -6
  16. nautobot/circuits/templates/circuits/inc/circuit_termination_speed_fragment.html +3 -3
  17. nautobot/circuits/templates/circuits/inc/speed_widget.html +13 -13
  18. nautobot/circuits/templates/circuits/provider_create.html +9 -9
  19. nautobot/circuits/tests/integration/test_circuit.py +19 -19
  20. nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +3 -0
  21. nautobot/circuits/tests/integration/test_relationships.py +4 -12
  22. nautobot/circuits/views.py +0 -2
  23. nautobot/cloud/filters.py +1 -13
  24. nautobot/cloud/navigation.py +3 -1
  25. nautobot/cloud/templates/cloud/cloudnetwork_update.html +9 -9
  26. nautobot/cloud/templates/cloud/cloudservice_update.html +6 -6
  27. nautobot/core/api/fields.py +30 -2
  28. nautobot/core/api/schema.py +1 -1
  29. nautobot/core/api/serializers.py +9 -2
  30. nautobot/core/api/urls.py +2 -0
  31. nautobot/core/api/views.py +58 -37
  32. nautobot/core/apps/__init__.py +6 -12
  33. nautobot/core/branching.py +83 -0
  34. nautobot/core/celery/__init__.py +11 -6
  35. nautobot/core/celery/backends.py +2 -0
  36. nautobot/core/celery/encoders.py +7 -0
  37. nautobot/core/celery/task.py +44 -0
  38. nautobot/core/checks.py +60 -0
  39. nautobot/core/cli/bootstrap_v3_to_v5.py +776 -0
  40. nautobot/core/constants.py +9 -0
  41. nautobot/core/context_processors.py +84 -0
  42. nautobot/core/filters.py +131 -2
  43. nautobot/core/forms/__init__.py +4 -2
  44. nautobot/core/forms/fields.py +10 -8
  45. nautobot/core/forms/forms.py +21 -9
  46. nautobot/core/forms/search.py +0 -15
  47. nautobot/core/forms/widgets.py +3 -2
  48. nautobot/core/graphql/__init__.py +8 -26
  49. nautobot/core/graphql/generators.py +16 -6
  50. nautobot/core/graphql/schema.py +1 -1
  51. nautobot/core/graphql/schema_init.py +1 -2
  52. nautobot/core/graphql/utils.py +7 -9
  53. nautobot/core/jobs/__init__.py +158 -0
  54. nautobot/core/management/commands/generate_test_data.py +28 -9
  55. nautobot/core/models/__init__.py +17 -2
  56. nautobot/core/models/fields.py +3 -2
  57. nautobot/core/models/generics.py +9 -1
  58. nautobot/core/models/name_color_content_types.py +1 -1
  59. nautobot/core/models/ordering.py +7 -5
  60. nautobot/core/models/querysets.py +77 -2
  61. nautobot/core/models/tree_queries.py +6 -4
  62. nautobot/core/settings.py +30 -16
  63. nautobot/core/settings.yaml +13 -7
  64. nautobot/core/tables.py +114 -44
  65. nautobot/core/templates/403.html +1 -1
  66. nautobot/core/templates/403_csrf_failure.html +1 -1
  67. nautobot/core/templates/404.html +1 -1
  68. nautobot/core/templates/40x.html +8 -8
  69. nautobot/core/templates/500.html +10 -10
  70. nautobot/core/templates/about.html +13 -12
  71. nautobot/core/templates/admin/actions.html +1 -1
  72. nautobot/core/templates/admin/app_index.html +3 -3
  73. nautobot/core/templates/admin/base.html +45 -52
  74. nautobot/core/templates/admin/base_site.html +0 -9
  75. nautobot/core/templates/admin/change_form.html +5 -5
  76. nautobot/core/templates/admin/change_list.html +8 -12
  77. nautobot/core/templates/admin/change_list_results.html +3 -3
  78. nautobot/core/templates/admin/config/config.html +24 -24
  79. nautobot/core/templates/admin/delete_confirmation.html +5 -5
  80. nautobot/core/templates/admin/edit_inline/stacked.html +5 -5
  81. nautobot/core/templates/admin/edit_inline/tabular.html +3 -3
  82. nautobot/core/templates/admin/includes/fieldset.html +15 -15
  83. nautobot/core/templates/admin/index.html +8 -8
  84. nautobot/core/templates/admin/submit_line.html +5 -5
  85. nautobot/core/templates/base_django.html +36 -32
  86. nautobot/core/templates/buttons/add.html +1 -1
  87. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +2 -2
  88. nautobot/core/templates/buttons/export.html +17 -18
  89. nautobot/core/templates/buttons/job_import.html +2 -2
  90. nautobot/core/templates/components/breadcrumbs.html +19 -17
  91. nautobot/core/templates/components/button/dropdown.html +7 -5
  92. nautobot/core/templates/components/echarts.html +2 -0
  93. nautobot/core/templates/components/layout/one_over_two.html +3 -3
  94. nautobot/core/templates/components/layout/two_over_one.html +3 -3
  95. nautobot/core/templates/components/panel/body_content_data_table.html +2 -2
  96. nautobot/core/templates/components/panel/body_content_tags.html +1 -1
  97. nautobot/core/templates/components/panel/body_wrapper_generic.html +4 -2
  98. nautobot/core/templates/components/panel/body_wrapper_generic_table.html +1 -1
  99. nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +5 -3
  100. nautobot/core/templates/components/panel/body_wrapper_table.html +4 -2
  101. nautobot/core/templates/components/panel/footer_contacts_table.html +4 -4
  102. nautobot/core/templates/components/panel/footer_content_table.html +3 -3
  103. nautobot/core/templates/components/panel/grouping_toggle.html +12 -11
  104. nautobot/core/templates/components/panel/header_extra_content_table.html +2 -11
  105. nautobot/core/templates/components/panel/panel.html +6 -3
  106. nautobot/core/templates/components/panel/stats_panel_body.html +9 -7
  107. nautobot/core/templates/components/tab/content_wrapper.html +29 -1
  108. nautobot/core/templates/components/tab/label_wrapper.html +10 -2
  109. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +11 -4
  110. nautobot/core/templates/echarts/echarts.html +20 -0
  111. nautobot/core/templates/exceptions/import_error.html +2 -2
  112. nautobot/core/templates/exceptions/permission_error.html +1 -1
  113. nautobot/core/templates/exceptions/programming_error.html +2 -2
  114. nautobot/core/templates/generic/object_bulk_add_component.html +29 -20
  115. nautobot/core/templates/generic/object_bulk_create.html +87 -75
  116. nautobot/core/templates/generic/object_bulk_destroy.html +35 -37
  117. nautobot/core/templates/generic/object_bulk_remove.html +30 -26
  118. nautobot/core/templates/generic/object_bulk_rename.html +53 -40
  119. nautobot/core/templates/generic/object_bulk_update.html +36 -29
  120. nautobot/core/templates/generic/object_create.html +40 -27
  121. nautobot/core/templates/generic/object_import.html +36 -24
  122. nautobot/core/templates/generic/object_list.html +279 -215
  123. nautobot/core/templates/generic/object_notes.html +21 -11
  124. nautobot/core/templates/generic/object_retrieve.html +161 -213
  125. nautobot/core/templates/graphene/graphiql.html +113 -60
  126. nautobot/core/templates/home.html +164 -87
  127. nautobot/core/templates/import_success.html +3 -2
  128. nautobot/core/templates/inc/ajax_loader.html +1 -1
  129. nautobot/core/templates/inc/computed_fields/panel_data.html +25 -13
  130. nautobot/core/templates/inc/created_updated.html +12 -7
  131. nautobot/core/templates/inc/custom_fields/panel_data.html +28 -16
  132. nautobot/core/templates/inc/custom_fields_panel.html +3 -3
  133. nautobot/core/templates/inc/dynamic_groups_panel.html +3 -3
  134. nautobot/core/templates/inc/extras_features_edit_form_fields.html +15 -15
  135. nautobot/core/templates/inc/footer.html +90 -40
  136. nautobot/core/templates/inc/form_static_field.html +6 -0
  137. nautobot/core/templates/inc/header.html +75 -0
  138. nautobot/core/templates/inc/header_banners.html +17 -0
  139. nautobot/core/templates/inc/header_messages.html +6 -0
  140. nautobot/core/templates/inc/image_attachments.html +9 -9
  141. nautobot/core/templates/inc/javascript.html +7 -24
  142. nautobot/core/templates/inc/media.html +4 -29
  143. nautobot/core/templates/inc/modal.html +2 -2
  144. nautobot/core/templates/inc/nav_favorites.html +27 -0
  145. nautobot/core/templates/inc/nav_menu.html +150 -108
  146. nautobot/core/templates/inc/object_details_advanced_panel.html +84 -71
  147. nautobot/core/templates/inc/page_title.html +23 -0
  148. nautobot/core/templates/inc/paginator.html +39 -28
  149. nautobot/core/templates/inc/relationships/panel_override.html +3 -3
  150. nautobot/core/templates/inc/relationships_panel.html +3 -3
  151. nautobot/core/templates/inc/relationships_table_rows.html +1 -1
  152. nautobot/core/templates/inc/search_panel.html +22 -16
  153. nautobot/core/templates/inc/table.html +61 -36
  154. nautobot/core/templates/inc/tenancy_form_panel.html +3 -3
  155. nautobot/core/templates/login.html +17 -59
  156. nautobot/core/templates/modals/modal_theme.html +12 -23
  157. nautobot/core/templates/nautobot_config.py.j2 +6 -5
  158. nautobot/core/templates/panel_table.html +8 -12
  159. nautobot/core/templates/redoc_ui.html +80 -0
  160. nautobot/core/templates/rest_framework/api.html +43 -21
  161. nautobot/core/templates/search.html +12 -13
  162. nautobot/core/templates/swagger_ui.html +19 -4
  163. nautobot/core/templates/system_jobs/import_objects.html +70 -58
  164. nautobot/core/templates/template.css +0 -6
  165. nautobot/core/templates/utilities/comment_form.html +34 -0
  166. nautobot/core/templates/utilities/confirmation_form.html +17 -9
  167. nautobot/core/templates/utilities/obj_table.html +19 -11
  168. nautobot/core/templates/utilities/render_field.html +27 -21
  169. nautobot/core/templates/utilities/render_jinja2.html +22 -25
  170. nautobot/core/templates/utilities/templatetags/advanced_filter_indicator.html +8 -0
  171. nautobot/core/templates/utilities/templatetags/badge.html +1 -1
  172. nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +2 -3
  173. nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +482 -0
  174. nautobot/core/templates/utilities/templatetags/modal_form_as_dialog.html +14 -18
  175. nautobot/core/templates/utilities/templatetags/saved_view_modal.html +11 -11
  176. nautobot/core/templates/utilities/templatetags/table_config_form.html +51 -24
  177. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  178. nautobot/core/templates/utilities/templatetags/utilization_graph.html +3 -3
  179. nautobot/core/templates/utilities/theme_preview.html +829 -566
  180. nautobot/core/templates/utilities/worker_status.html +42 -41
  181. nautobot/core/templates/widgets/selectwithdisabled_option.html +3 -1
  182. nautobot/core/templates/widgets/sluginput.html +2 -2
  183. nautobot/core/templatetags/buttons.py +38 -40
  184. nautobot/core/templatetags/helpers.py +105 -28
  185. nautobot/core/templatetags/ui_framework.py +17 -0
  186. nautobot/core/testing/api.py +76 -12
  187. nautobot/core/testing/filters.py +11 -27
  188. nautobot/core/testing/integration.py +128 -10
  189. nautobot/core/testing/mixins.py +7 -4
  190. nautobot/core/testing/utils.py +28 -5
  191. nautobot/core/testing/views.py +125 -27
  192. nautobot/core/tests/integration/test_app_home.py +39 -35
  193. nautobot/core/tests/integration/test_app_navbar.py +60 -67
  194. nautobot/core/tests/integration/test_filters.py +123 -55
  195. nautobot/core/tests/integration/test_general_functionality.py +1 -1
  196. nautobot/core/tests/integration/test_home.py +10 -18
  197. nautobot/core/tests/integration/test_import_objects_ui.py +2 -9
  198. nautobot/core/tests/integration/test_navbar.py +41 -16
  199. nautobot/core/tests/integration/test_swagger.py +1 -7
  200. nautobot/core/tests/integration/test_theme.py +3 -0
  201. nautobot/core/tests/nautobot_config_without_example_apps.py +4 -0
  202. nautobot/core/tests/runner.py +6 -1
  203. nautobot/core/tests/test_api.py +5 -3
  204. nautobot/core/tests/test_branching.py +154 -0
  205. nautobot/core/tests/test_breadcrumbs.py +7 -8
  206. nautobot/core/tests/test_checks.py +28 -0
  207. nautobot/core/tests/test_commands.py +0 -41
  208. nautobot/core/tests/test_config.py +2 -1
  209. nautobot/core/tests/test_csv.py +4 -7
  210. nautobot/core/tests/test_filters.py +326 -318
  211. nautobot/core/tests/test_forms.py +19 -30
  212. nautobot/core/tests/test_graphql.py +67 -57
  213. nautobot/core/tests/test_models.py +1 -1
  214. nautobot/core/tests/test_nautobot_server.py +2 -0
  215. nautobot/core/tests/test_navigations.py +78 -10
  216. nautobot/core/tests/test_tables.py +3 -1
  217. nautobot/core/tests/test_templatetags_helpers.py +61 -21
  218. nautobot/core/tests/test_templatetags_ui_framework.py +36 -18
  219. nautobot/core/tests/test_ui.py +207 -2
  220. nautobot/core/tests/test_utils.py +147 -2
  221. nautobot/core/tests/test_views.py +201 -64
  222. nautobot/core/tests/test_views_utils.py +1 -1
  223. nautobot/core/ui/breadcrumbs.py +2 -12
  224. nautobot/core/ui/choices.py +190 -0
  225. nautobot/core/ui/constants.py +86 -0
  226. nautobot/core/ui/echarts.py +474 -0
  227. nautobot/core/ui/nav.py +5 -1
  228. nautobot/core/ui/object_detail.py +180 -16
  229. nautobot/core/urls.py +13 -1
  230. nautobot/core/utils/cache.py +71 -0
  231. nautobot/core/utils/data.py +8 -5
  232. nautobot/core/utils/filtering.py +8 -2
  233. nautobot/core/utils/git.py +3 -3
  234. nautobot/core/utils/lookup.py +87 -13
  235. nautobot/core/utils/migrations.py +22 -0
  236. nautobot/core/utils/module_loading.py +26 -0
  237. nautobot/core/utils/permissions.py +9 -5
  238. nautobot/core/views/__init__.py +114 -63
  239. nautobot/core/views/generic.py +34 -27
  240. nautobot/core/views/mixins.py +49 -27
  241. nautobot/core/views/renderers.py +3 -5
  242. nautobot/core/views/utils.py +10 -5
  243. nautobot/core/views/viewsets.py +2 -1
  244. nautobot/data_validation/__init__.py +0 -0
  245. nautobot/data_validation/api/__init__.py +1 -0
  246. nautobot/data_validation/api/serializers.py +80 -0
  247. nautobot/data_validation/api/urls.py +20 -0
  248. nautobot/data_validation/api/views.py +44 -0
  249. nautobot/data_validation/apps.py +18 -0
  250. nautobot/data_validation/custom_validators.py +330 -0
  251. nautobot/data_validation/filters.py +133 -0
  252. nautobot/data_validation/form_mixin.py +25 -0
  253. nautobot/data_validation/forms.py +342 -0
  254. nautobot/data_validation/migrations/0001_initial.py +224 -0
  255. nautobot/data_validation/migrations/0002_data_migration_from_app.py +324 -0
  256. nautobot/data_validation/migrations/__init__.py +0 -0
  257. nautobot/data_validation/models.py +361 -0
  258. nautobot/data_validation/navigation.py +74 -0
  259. nautobot/data_validation/signals.py +30 -0
  260. nautobot/data_validation/tables.py +259 -0
  261. nautobot/data_validation/templates/data_validation/datacompliance_retrieve.html +1 -0
  262. nautobot/data_validation/templates/data_validation/datacompliance_tab.html +11 -0
  263. nautobot/data_validation/templates/data_validation/device_constraints.html +61 -0
  264. nautobot/data_validation/tests/__init__.py +20 -0
  265. nautobot/data_validation/tests/migrations/__init__.py +0 -0
  266. nautobot/data_validation/tests/migrations/test_migrations.py +489 -0
  267. nautobot/data_validation/tests/test_api.py +238 -0
  268. nautobot/data_validation/tests/test_custom_validators.py +423 -0
  269. nautobot/data_validation/tests/test_data_compliance_rules.py +85 -0
  270. nautobot/data_validation/tests/test_filters.py +240 -0
  271. nautobot/data_validation/tests/test_form_mixin.py +115 -0
  272. nautobot/data_validation/tests/test_models.py +393 -0
  273. nautobot/data_validation/tests/test_views.py +435 -0
  274. nautobot/data_validation/urls.py +21 -0
  275. nautobot/data_validation/views.py +227 -0
  276. nautobot/dcim/api/serializers.py +10 -13
  277. nautobot/dcim/api/urls.py +2 -0
  278. nautobot/dcim/api/views.py +7 -0
  279. nautobot/dcim/apps.py +4 -0
  280. nautobot/dcim/choices.py +16 -0
  281. nautobot/dcim/custom_validators.py +84 -0
  282. nautobot/dcim/filter_mixins.py +353 -4
  283. nautobot/dcim/{filters/__init__.py → filters.py} +70 -157
  284. nautobot/dcim/forms.py +12 -6
  285. nautobot/dcim/graphql/types.py +1 -0
  286. nautobot/dcim/migrations/0075_add_deviceclusterassignment.py +52 -0
  287. nautobot/dcim/migrations/0076_device_cluster_to_clusters_data_migration.py +40 -0
  288. nautobot/dcim/migrations/0077_remove_device_cluster.py +14 -0
  289. nautobot/dcim/migrations/0078_remove_device_location_tenant_name_uniqueness.py +16 -0
  290. nautobot/dcim/migrations/0079_device_name_data_migration.py +59 -0
  291. nautobot/dcim/models/__init__.py +2 -0
  292. nautobot/dcim/models/device_components.py +3 -1
  293. nautobot/dcim/models/devices.py +115 -51
  294. nautobot/dcim/navigation.py +7 -3
  295. nautobot/dcim/querysets.py +6 -0
  296. nautobot/dcim/signals.py +19 -0
  297. nautobot/dcim/tables/devices.py +9 -5
  298. nautobot/dcim/tables/template_code.py +191 -102
  299. nautobot/dcim/templates/dcim/cable.html +1 -1
  300. nautobot/dcim/templates/dcim/cable_connect.html +62 -146
  301. nautobot/dcim/templates/dcim/cable_retrieve.html +10 -10
  302. nautobot/dcim/templates/dcim/cable_trace.html +15 -17
  303. nautobot/dcim/templates/dcim/console_port_connection_list.html +2 -2
  304. nautobot/dcim/templates/dcim/consoleport.html +18 -17
  305. nautobot/dcim/templates/dcim/consoleserverport.html +18 -17
  306. nautobot/dcim/templates/dcim/controller_create.html +12 -8
  307. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +1 -1
  308. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +6 -6
  309. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +1 -1
  310. nautobot/dcim/templates/dcim/device/config.html +17 -19
  311. nautobot/dcim/templates/dcim/device/lldp_neighbors.html +4 -4
  312. nautobot/dcim/templates/dcim/device/status.html +20 -20
  313. nautobot/dcim/templates/dcim/device_component_add.html +24 -15
  314. nautobot/dcim/templates/dcim/device_create.html +120 -120
  315. nautobot/dcim/templates/dcim/device_list.html +75 -12
  316. nautobot/dcim/templates/dcim/devicebay.html +7 -7
  317. nautobot/dcim/templates/dcim/devicebay_populate.html +29 -23
  318. nautobot/dcim/templates/dcim/deviceredundancygroup_create.html +6 -6
  319. nautobot/dcim/templates/dcim/devicetype.html +1 -1
  320. nautobot/dcim/templates/dcim/devicetype_component_add.html +25 -19
  321. nautobot/dcim/templates/dcim/devicetype_list.html +4 -4
  322. nautobot/dcim/templates/dcim/devicetype_update.html +9 -9
  323. nautobot/dcim/templates/dcim/footer_convert_to_contact_or_team_record.html +3 -3
  324. nautobot/dcim/templates/dcim/frontport.html +21 -20
  325. nautobot/dcim/templates/dcim/inc/cable_form.html +7 -7
  326. nautobot/dcim/templates/dcim/inc/cable_termination.html +1 -1
  327. nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +18 -9
  328. nautobot/dcim/templates/dcim/inc/detail_softwareversion_softwareimagefile_rows.html +1 -1
  329. nautobot/dcim/templates/dcim/inc/device_interface_filter.html +1 -1
  330. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +10 -10
  331. nautobot/dcim/templates/dcim/inc/edit_form_softwareversion_js.html +2 -2
  332. nautobot/dcim/templates/dcim/inc/homepage_connections.html +2 -2
  333. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +10 -10
  334. nautobot/dcim/templates/dcim/inc/rack_elevation.html +2 -2
  335. nautobot/dcim/templates/dcim/interface.html +42 -22
  336. nautobot/dcim/templates/dcim/interface_connection_list.html +2 -2
  337. nautobot/dcim/templates/dcim/interface_edit.html +26 -11
  338. nautobot/dcim/templates/dcim/interfaceredundancygroupassociation_create.html +3 -3
  339. nautobot/dcim/templates/dcim/inventoryitem.html +3 -3
  340. nautobot/dcim/templates/dcim/inventoryitem_add.html +21 -10
  341. nautobot/dcim/templates/dcim/inventoryitem_bulk_delete.html +1 -1
  342. nautobot/dcim/templates/dcim/inventoryitem_edit.html +6 -4
  343. nautobot/dcim/templates/dcim/location.html +1 -1
  344. nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +24 -18
  345. nautobot/dcim/templates/dcim/location_retrieve.html +1 -1
  346. nautobot/dcim/templates/dcim/location_update.html +9 -9
  347. nautobot/dcim/templates/dcim/locationtype.html +0 -1
  348. nautobot/dcim/templates/dcim/module/base.html +67 -27
  349. nautobot/dcim/templates/dcim/module_consoleports.html +13 -15
  350. nautobot/dcim/templates/dcim/module_consoleserverports.html +13 -15
  351. nautobot/dcim/templates/dcim/module_frontports.html +13 -15
  352. nautobot/dcim/templates/dcim/module_interfaces.html +14 -16
  353. nautobot/dcim/templates/dcim/module_list.html +59 -10
  354. nautobot/dcim/templates/dcim/module_modulebays.html +12 -14
  355. nautobot/dcim/templates/dcim/module_poweroutlets.html +13 -15
  356. nautobot/dcim/templates/dcim/module_powerports.html +13 -15
  357. nautobot/dcim/templates/dcim/module_rearports.html +13 -15
  358. nautobot/dcim/templates/dcim/module_retrieve.html +3 -3
  359. nautobot/dcim/templates/dcim/module_update.html +15 -9
  360. nautobot/dcim/templates/dcim/modulebay_retrieve.html +0 -93
  361. nautobot/dcim/templates/dcim/modulefamily_retrieve.html +7 -7
  362. nautobot/dcim/templates/dcim/moduletype_list.html +2 -2
  363. nautobot/dcim/templates/dcim/moduletype_retrieve.html +74 -35
  364. nautobot/dcim/templates/dcim/platform_create.html +9 -9
  365. nautobot/dcim/templates/dcim/power_port_connection_list.html +3 -3
  366. nautobot/dcim/templates/dcim/powerfeed.html +1 -1
  367. nautobot/dcim/templates/dcim/powerfeed_edit.html +15 -15
  368. nautobot/dcim/templates/dcim/poweroutlet.html +13 -13
  369. nautobot/dcim/templates/dcim/powerpanel.html +1 -1
  370. nautobot/dcim/templates/dcim/powerport.html +17 -16
  371. nautobot/dcim/templates/dcim/rack.html +1 -1
  372. nautobot/dcim/templates/dcim/rack_elevation.html +2 -2
  373. nautobot/dcim/templates/dcim/rack_elevation_list.html +21 -9
  374. nautobot/dcim/templates/dcim/rack_retrieve.html +75 -57
  375. nautobot/dcim/templates/dcim/rack_update.html +14 -14
  376. nautobot/dcim/templates/dcim/rackreservation.html +1 -1
  377. nautobot/dcim/templates/dcim/rackreservation_edit.html +6 -6
  378. nautobot/dcim/templates/dcim/rearport.html +19 -18
  379. nautobot/dcim/templates/dcim/trace/cable.html +1 -1
  380. nautobot/dcim/templates/dcim/trace/circuit.html +1 -1
  381. nautobot/dcim/templates/dcim/trace/device.html +1 -1
  382. nautobot/dcim/templates/dcim/trace/powerpanel.html +1 -1
  383. nautobot/dcim/templates/dcim/trace/termination.html +1 -1
  384. nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
  385. nautobot/dcim/templates/dcim/virtualchassis_add_member.html +25 -16
  386. nautobot/dcim/templates/dcim/virtualchassis_create.html +6 -6
  387. nautobot/dcim/templates/dcim/virtualchassis_edit.html +1 -1
  388. nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +1 -1
  389. nautobot/dcim/templates/dcim/virtualchassis_update.html +36 -22
  390. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +9 -9
  391. nautobot/dcim/tests/integration/test_controller.py +6 -6
  392. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +7 -7
  393. nautobot/dcim/tests/integration/test_create_device.py +9 -9
  394. nautobot/dcim/tests/integration/test_device_bulk_operations.py +7 -2
  395. nautobot/dcim/tests/integration/test_fileinputpicker.py +5 -7
  396. nautobot/dcim/tests/integration/test_location_bulk_operations.py +2 -0
  397. nautobot/dcim/tests/integration/test_module_bay_position.py +4 -1
  398. nautobot/dcim/tests/test_api.py +86 -6
  399. nautobot/dcim/tests/test_custom_validators.py +229 -0
  400. nautobot/dcim/tests/test_filters.py +159 -110
  401. nautobot/dcim/tests/test_graphql.py +32 -36
  402. nautobot/dcim/tests/test_jobs.py +1 -1
  403. nautobot/dcim/tests/test_models.py +229 -1
  404. nautobot/dcim/tests/test_views.py +31 -20
  405. nautobot/dcim/utils.py +3 -3
  406. nautobot/dcim/views.py +77 -41
  407. nautobot/extras/api/serializers.py +83 -19
  408. nautobot/extras/api/urls.py +7 -0
  409. nautobot/extras/api/views.py +243 -140
  410. nautobot/extras/choices.py +34 -13
  411. nautobot/extras/constants.py +1 -1
  412. nautobot/extras/context_managers.py +26 -26
  413. nautobot/extras/datasources/git.py +22 -0
  414. nautobot/extras/datasources/registry.py +3 -0
  415. nautobot/extras/exceptions.py +5 -0
  416. nautobot/extras/factory.py +11 -1
  417. nautobot/extras/{filters/mixins.py → filter_mixins.py} +4 -3
  418. nautobot/extras/{filters/__init__.py → filters.py} +203 -58
  419. nautobot/extras/forms/base.py +2 -1
  420. nautobot/extras/forms/forms.py +225 -20
  421. nautobot/extras/forms/mixins.py +0 -41
  422. nautobot/extras/homepage.py +21 -2
  423. nautobot/extras/jobs.py +2 -8
  424. nautobot/extras/jobs_ui.py +2 -2
  425. nautobot/extras/management/__init__.py +9 -0
  426. nautobot/extras/managers.py +31 -22
  427. nautobot/extras/migrations/0126_approval_workflow_pre_check.py +58 -0
  428. nautobot/extras/migrations/0127_approval_workflow_models.py +266 -0
  429. nautobot/extras/migrations/0128_remove_job_approval_required_and_more.py +29 -0
  430. nautobot/extras/migrations/0129_jobresult_debug_log_count_jobresult_error_log_count_and_more.py +37 -0
  431. nautobot/extras/migrations/0130_jobresult_generate_log_entry_counts.py +42 -0
  432. nautobot/extras/models/__init__.py +14 -3
  433. nautobot/extras/models/approvals.py +556 -0
  434. nautobot/extras/models/change_logging.py +1 -0
  435. nautobot/extras/models/contacts.py +2 -0
  436. nautobot/extras/models/customfields.py +57 -22
  437. nautobot/extras/models/datasources.py +21 -0
  438. nautobot/extras/models/groups.py +2 -0
  439. nautobot/extras/models/jobs.py +122 -39
  440. nautobot/extras/models/metadata.py +2 -3
  441. nautobot/extras/models/mixins.py +129 -1
  442. nautobot/extras/models/models.py +22 -14
  443. nautobot/extras/models/relationships.py +47 -10
  444. nautobot/extras/models/secrets.py +1 -0
  445. nautobot/extras/models/statuses.py +0 -15
  446. nautobot/extras/models/tags.py +1 -1
  447. nautobot/extras/navigation.py +42 -15
  448. nautobot/extras/plugins/__init__.py +33 -55
  449. nautobot/extras/plugins/marketplace_manifest.yml +1 -23
  450. nautobot/extras/plugins/tables.py +8 -6
  451. nautobot/extras/plugins/urls.py +2 -21
  452. nautobot/extras/plugins/utils.py +1 -33
  453. nautobot/extras/plugins/validators.py +10 -10
  454. nautobot/extras/plugins/views.py +1 -5
  455. nautobot/extras/querysets.py +17 -21
  456. nautobot/extras/signals.py +23 -8
  457. nautobot/extras/tables.py +420 -99
  458. nautobot/extras/templates/extras/approval_dashboard.html +15 -0
  459. nautobot/extras/templates/extras/approval_workflow/approve.html +11 -0
  460. nautobot/extras/templates/extras/approval_workflow/comment.html +9 -0
  461. nautobot/extras/templates/extras/approval_workflow/deny.html +10 -0
  462. nautobot/extras/templates/extras/approvalworkflowdefinition_update.html +77 -0
  463. nautobot/extras/templates/extras/approvalworkflowstage_retrieve.html +29 -0
  464. nautobot/extras/templates/extras/configcontext_update.html +12 -12
  465. nautobot/extras/templates/extras/configcontextschema.html +1 -1
  466. nautobot/extras/templates/extras/configcontextschema_retrieve.html +9 -9
  467. nautobot/extras/templates/extras/configcontextschema_update.html +6 -6
  468. nautobot/extras/templates/extras/configcontextschema_validation.html +2 -2
  469. nautobot/extras/templates/extras/customfield_update.html +12 -12
  470. nautobot/extras/templates/extras/dynamicgroup.html +1 -1
  471. nautobot/extras/templates/extras/dynamicgroup_edit.html +1 -1
  472. nautobot/extras/templates/extras/dynamicgroup_retrieve.html +17 -17
  473. nautobot/extras/templates/extras/dynamicgroup_update.html +24 -24
  474. nautobot/extras/templates/extras/externalintegration_update.html +6 -6
  475. nautobot/extras/templates/extras/gitrepository.html +1 -1
  476. nautobot/extras/templates/extras/gitrepository_object_edit.html +1 -1
  477. nautobot/extras/templates/extras/gitrepository_result.html +1 -1
  478. nautobot/extras/templates/extras/gitrepository_retrieve.html +12 -12
  479. nautobot/extras/templates/extras/gitrepository_update.html +25 -7
  480. nautobot/extras/templates/extras/graphqlquery_retrieve.html +1 -1
  481. nautobot/extras/templates/extras/inc/approval_buttons_column.html +38 -0
  482. nautobot/extras/templates/extras/inc/bulk_edit_overridable_field.html +14 -13
  483. nautobot/extras/templates/extras/inc/configcontext_format.html +11 -4
  484. nautobot/extras/templates/extras/inc/graphqlquery_execute.html +7 -7
  485. nautobot/extras/templates/extras/inc/job_label.html +5 -5
  486. nautobot/extras/templates/extras/inc/job_table.html +23 -10
  487. nautobot/extras/templates/extras/inc/job_tiles.html +33 -21
  488. nautobot/extras/templates/extras/inc/jobresult.html +6 -6
  489. nautobot/extras/templates/extras/inc/json_format.html +11 -4
  490. nautobot/extras/templates/extras/inc/object_contact_header.html +6 -6
  491. nautobot/extras/templates/extras/inc/overridable_field.html +16 -15
  492. nautobot/extras/templates/extras/inc/panel_approvalworkflowstage.html +34 -0
  493. nautobot/extras/templates/extras/inc/panel_changelog.html +9 -9
  494. nautobot/extras/templates/extras/inc/panel_jobhistory.html +8 -6
  495. nautobot/extras/templates/extras/inc/tags_panel.html +3 -3
  496. nautobot/extras/templates/extras/job.html +154 -155
  497. nautobot/extras/templates/extras/job_approval_confirmation.html +4 -27
  498. nautobot/extras/templates/extras/job_bulk_edit.html +18 -1
  499. nautobot/extras/templates/extras/job_detail.html +1 -1
  500. nautobot/extras/templates/extras/job_edit.html +69 -64
  501. nautobot/extras/templates/extras/job_list.html +37 -60
  502. nautobot/extras/templates/extras/jobresult.html +1 -1
  503. nautobot/extras/templates/extras/jobresult_retrieve.html +17 -17
  504. nautobot/extras/templates/extras/marketplace.html +62 -71
  505. nautobot/extras/templates/extras/metadatatype_create.html +9 -9
  506. nautobot/extras/templates/extras/note.html +1 -1
  507. nautobot/extras/templates/extras/object_approvalworkflow.html +36 -0
  508. nautobot/extras/templates/extras/object_assign_contact_or_team.html +16 -7
  509. nautobot/extras/templates/extras/object_configcontext.html +20 -20
  510. nautobot/extras/templates/extras/object_new_contact.html +6 -6
  511. nautobot/extras/templates/extras/object_new_team.html +6 -6
  512. nautobot/extras/templates/extras/objectchange.html +1 -1
  513. nautobot/extras/templates/extras/objectchange_retrieve.html +37 -56
  514. nautobot/extras/templates/extras/plugin_detail.html +40 -41
  515. nautobot/extras/templates/extras/plugins_list.html +23 -38
  516. nautobot/extras/templates/extras/plugins_tiles.html +28 -28
  517. nautobot/extras/templates/extras/role_retrieve.html +112 -48
  518. nautobot/extras/templates/extras/scheduledjob.html +25 -28
  519. nautobot/extras/templates/extras/secret_create.html +11 -11
  520. nautobot/extras/templates/extras/secretsgroup_update.html +6 -6
  521. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +3 -3
  522. nautobot/extras/templates/extras/status.html +1 -1
  523. nautobot/extras/templates/extras/tag.html +1 -1
  524. nautobot/extras/templates/extras/tag_update.html +3 -3
  525. nautobot/extras/templates/extras/templatetags/log_level.html +1 -1
  526. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -2
  527. nautobot/extras/templates/extras/webhook.html +12 -12
  528. nautobot/extras/templatetags/approvals.py +19 -0
  529. nautobot/extras/templatetags/custom_links.py +12 -12
  530. nautobot/extras/templatetags/job_buttons.py +14 -12
  531. nautobot/extras/test_jobs/invalid_import.py +9 -0
  532. nautobot/extras/test_jobs/log_counts_by_level.py +23 -0
  533. nautobot/extras/test_jobs/missing_import.py +11 -0
  534. nautobot/extras/tests/integration/test_computedfields.py +5 -8
  535. nautobot/extras/tests/integration/test_configcontextschema.py +43 -48
  536. nautobot/extras/tests/integration/test_customfields.py +33 -33
  537. nautobot/extras/tests/integration/test_dynamicgroups.py +5 -10
  538. nautobot/extras/tests/integration/test_jobs.py +2 -4
  539. nautobot/extras/tests/integration/test_notes.py +3 -9
  540. nautobot/extras/tests/integration/test_plugin_banner.py +3 -0
  541. nautobot/extras/tests/integration/test_plugins.py +35 -27
  542. nautobot/extras/tests/integration/test_relationships.py +7 -11
  543. nautobot/extras/tests/integration/test_tagfilter.py +3 -11
  544. nautobot/extras/tests/test_api.py +786 -242
  545. nautobot/extras/tests/test_approvals.py +715 -0
  546. nautobot/extras/tests/test_changelog.py +18 -14
  547. nautobot/extras/tests/test_customfields.py +14 -13
  548. nautobot/extras/tests/test_datasources.py +1 -1
  549. nautobot/extras/tests/test_dynamicgroups.py +9 -4
  550. nautobot/extras/tests/test_filters.py +443 -13
  551. nautobot/extras/tests/test_forms.py +18 -57
  552. nautobot/extras/tests/test_jobs.py +25 -4
  553. nautobot/extras/tests/test_migrations.py +81 -1
  554. nautobot/extras/tests/test_models.py +378 -47
  555. nautobot/extras/tests/test_plugins.py +47 -13
  556. nautobot/extras/tests/test_relationships.py +7 -2
  557. nautobot/extras/tests/test_utils.py +2 -0
  558. nautobot/extras/tests/test_views.py +780 -493
  559. nautobot/extras/urls.py +36 -12
  560. nautobot/extras/utils.py +58 -12
  561. nautobot/extras/views.py +668 -209
  562. nautobot/ipam/factory.py +7 -0
  563. nautobot/ipam/filter_mixins.py +38 -0
  564. nautobot/ipam/filters.py +35 -71
  565. nautobot/ipam/formfields.py +1 -1
  566. nautobot/ipam/forms.py +6 -3
  567. nautobot/ipam/migrations/0030_ipam__namespaces.py +13 -0
  568. nautobot/ipam/migrations/0031_ipam___data_migrations.py +4 -1
  569. nautobot/ipam/migrations/0054_namespace_tenant.py +25 -0
  570. nautobot/ipam/models.py +29 -2
  571. nautobot/ipam/navigation.py +3 -1
  572. nautobot/ipam/querysets.py +1 -2
  573. nautobot/ipam/tables.py +26 -17
  574. nautobot/ipam/templates/ipam/inc/ipadress_edit_header.html +6 -6
  575. nautobot/ipam/templates/ipam/inc/service.html +8 -8
  576. nautobot/ipam/templates/ipam/inc/toggle_available.html +10 -10
  577. nautobot/ipam/templates/ipam/inc/vlangroup_header.html +3 -2
  578. nautobot/ipam/templates/ipam/ipaddress.html +27 -13
  579. nautobot/ipam/templates/ipam/ipaddress_assign.html +31 -24
  580. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +3 -3
  581. nautobot/ipam/templates/ipam/ipaddress_edit.html +9 -9
  582. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +7 -9
  583. nautobot/ipam/templates/ipam/ipaddress_merge.html +195 -186
  584. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +7 -9
  585. nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +7 -5
  586. nautobot/ipam/templates/ipam/namespace_ip_addresses.html +1 -1
  587. nautobot/ipam/templates/ipam/namespace_prefixes.html +1 -1
  588. nautobot/ipam/templates/ipam/namespace_update.html +15 -0
  589. nautobot/ipam/templates/ipam/namespace_vrfs.html +1 -1
  590. nautobot/ipam/templates/ipam/prefix_create.html +9 -9
  591. nautobot/ipam/templates/ipam/prefix_list.html +15 -14
  592. nautobot/ipam/templates/ipam/prefix_retrieve.html +0 -1
  593. nautobot/ipam/templates/ipam/vlan.html +1 -1
  594. nautobot/ipam/templates/ipam/vlan_interfaces.html +1 -1
  595. nautobot/ipam/templates/ipam/vlan_update.html +6 -6
  596. nautobot/ipam/templates/ipam/vlan_vminterfaces.html +1 -1
  597. nautobot/ipam/templates/ipam/vrf_edit.html +15 -15
  598. nautobot/ipam/tests/integration/test_prefixes.py +5 -13
  599. nautobot/ipam/tests/migration/test_migrations.py +89 -0
  600. nautobot/ipam/tests/test_api.py +20 -7
  601. nautobot/ipam/tests/test_filters.py +10 -0
  602. nautobot/ipam/tests/test_forms.py +1 -1
  603. nautobot/ipam/tests/test_models.py +1 -1
  604. nautobot/ipam/tests/test_tables.py +1 -2
  605. nautobot/ipam/tests/test_utils.py +1 -1
  606. nautobot/ipam/tests/test_views.py +24 -21
  607. nautobot/ipam/ui.py +0 -17
  608. nautobot/ipam/utils/migrations.py +16 -2
  609. nautobot/ipam/utils/testing.py +9 -3
  610. nautobot/ipam/views.py +49 -7
  611. nautobot/project-static/dist/css/graphql-libraries.css +655 -0
  612. nautobot/project-static/dist/css/graphql-libraries.css.map +1 -0
  613. nautobot/project-static/dist/css/materialdesignicons.css +3 -0
  614. nautobot/project-static/dist/css/materialdesignicons.css.map +1 -0
  615. nautobot/project-static/dist/css/nautobot.css +13 -0
  616. nautobot/project-static/dist/css/nautobot.css.map +1 -0
  617. nautobot/project-static/dist/js/graphql-libraries.js +3 -0
  618. nautobot/project-static/dist/js/graphql-libraries.js.LICENSE.txt +62 -0
  619. nautobot/project-static/dist/js/graphql-libraries.js.map +1 -0
  620. nautobot/project-static/dist/js/libraries.js +3 -0
  621. nautobot/project-static/dist/js/libraries.js.LICENSE.txt +65 -0
  622. nautobot/project-static/dist/js/libraries.js.map +1 -0
  623. nautobot/project-static/dist/js/materialdesignicons.js +0 -0
  624. nautobot/project-static/dist/js/nautobot-graphiql.js +2 -0
  625. nautobot/project-static/dist/js/nautobot-graphiql.js.map +1 -0
  626. nautobot/project-static/dist/js/nautobot.js +2 -0
  627. nautobot/project-static/dist/js/nautobot.js.map +1 -0
  628. nautobot/project-static/fonts/Montserrat-v30-Bold.woff2 +0 -0
  629. nautobot/project-static/fonts/Montserrat-v30-Light.woff2 +0 -0
  630. nautobot/project-static/fonts/Montserrat-v30-Regular.woff2 +0 -0
  631. nautobot/project-static/fonts/Roboto-v48-Bold.woff2 +0 -0
  632. nautobot/project-static/fonts/Roboto-v48-Light.woff2 +0 -0
  633. nautobot/project-static/fonts/Roboto-v48-Regular.woff2 +0 -0
  634. nautobot/project-static/img/jinja_logo.svg +21 -92
  635. nautobot/project-static/js/cabletrace.js +1 -1
  636. nautobot/project-static/js/editor.js +4 -4
  637. nautobot/project-static/js/forms.js +67 -717
  638. nautobot/project-static/js/job_result.js +2 -2
  639. nautobot/project-static/nautobot-icons/360-degrees.svg +3 -0
  640. nautobot/project-static/nautobot-icons/arrow-decision.svg +3 -0
  641. nautobot/project-static/nautobot-icons/arrows-expand-rec.svg +3 -0
  642. nautobot/project-static/nautobot-icons/arrows-move-2-rec.svg +3 -0
  643. nautobot/project-static/nautobot-icons/arrows-move-rec.svg +3 -0
  644. nautobot/project-static/nautobot-icons/atom.svg +3 -0
  645. nautobot/project-static/nautobot-icons/battery-3.svg +3 -0
  646. nautobot/project-static/nautobot-icons/branch.svg +3 -0
  647. nautobot/project-static/nautobot-icons/briefcase-2.svg +3 -0
  648. nautobot/project-static/nautobot-icons/cable-data-2.svg +3 -0
  649. nautobot/project-static/nautobot-icons/cable-data.svg +3 -0
  650. nautobot/project-static/nautobot-icons/cast.svg +3 -0
  651. nautobot/project-static/nautobot-icons/check-circle.svg +3 -0
  652. nautobot/project-static/nautobot-icons/checkbox-circle.svg +3 -0
  653. nautobot/project-static/nautobot-icons/checkbox-rec.svg +3 -0
  654. nautobot/project-static/nautobot-icons/cloud-check.svg +3 -0
  655. nautobot/project-static/nautobot-icons/cloud-lightning.svg +3 -0
  656. nautobot/project-static/nautobot-icons/cloud-upload.svg +3 -0
  657. nautobot/project-static/nautobot-icons/cloud.svg +3 -0
  658. nautobot/project-static/nautobot-icons/compass.svg +3 -0
  659. nautobot/project-static/nautobot-icons/control-panel.svg +3 -0
  660. nautobot/project-static/nautobot-icons/credit-card.svg +3 -0
  661. nautobot/project-static/nautobot-icons/device-lifecycle.svg +3 -0
  662. nautobot/project-static/nautobot-icons/direction.svg +3 -0
  663. nautobot/project-static/nautobot-icons/elements.svg +3 -0
  664. nautobot/project-static/nautobot-icons/extensibility.svg +3 -0
  665. nautobot/project-static/nautobot-icons/globe-2.svg +3 -0
  666. nautobot/project-static/nautobot-icons/globe.svg +3 -0
  667. nautobot/project-static/nautobot-icons/hammer.svg +3 -0
  668. nautobot/project-static/nautobot-icons/history.svg +3 -0
  669. nautobot/project-static/nautobot-icons/ip.svg +3 -0
  670. nautobot/project-static/nautobot-icons/laptop.svg +3 -0
  671. nautobot/project-static/nautobot-icons/lightning.svg +3 -0
  672. nautobot/project-static/nautobot-icons/list-unordered.svg +3 -0
  673. nautobot/project-static/nautobot-icons/map-view.svg +3 -0
  674. nautobot/project-static/nautobot-icons/organization.svg +3 -0
  675. nautobot/project-static/nautobot-icons/pin-2.svg +3 -0
  676. nautobot/project-static/nautobot-icons/pin-3.svg +3 -0
  677. nautobot/project-static/nautobot-icons/plug.svg +3 -0
  678. nautobot/project-static/nautobot-icons/refresh-cw.svg +3 -0
  679. nautobot/project-static/nautobot-icons/rocket-2.svg +3 -0
  680. nautobot/project-static/nautobot-icons/rotate-cw.svg +3 -0
  681. nautobot/project-static/nautobot-icons/route.svg +3 -0
  682. nautobot/project-static/nautobot-icons/secrets.svg +3 -0
  683. nautobot/project-static/nautobot-icons/security.svg +3 -0
  684. nautobot/project-static/nautobot-icons/server-2.svg +3 -0
  685. nautobot/project-static/nautobot-icons/server.svg +3 -0
  686. nautobot/project-static/nautobot-icons/share.svg +3 -0
  687. nautobot/project-static/nautobot-icons/shield-check.svg +3 -0
  688. nautobot/project-static/nautobot-icons/sitemap-outline.svg +3 -0
  689. nautobot/project-static/nautobot-icons/sliders-vert-2.svg +3 -0
  690. nautobot/project-static/nautobot-icons/sliders-vert.svg +3 -0
  691. nautobot/project-static/nautobot-icons/star-filled.svg +3 -0
  692. nautobot/project-static/nautobot-icons/star.svg +3 -0
  693. nautobot/project-static/nautobot-icons/transform.svg +3 -0
  694. nautobot/project-static/nautobot-icons/wifi.svg +3 -0
  695. nautobot/tenancy/api/serializers.py +1 -0
  696. nautobot/tenancy/api/views.py +2 -1
  697. nautobot/tenancy/{filters/__init__.py → filters.py} +2 -10
  698. nautobot/tenancy/navigation.py +3 -1
  699. nautobot/tenancy/templates/tenancy/tenant_create.html +6 -6
  700. nautobot/tenancy/tests/test_filters.py +0 -2
  701. nautobot/tenancy/views.py +2 -1
  702. nautobot/ui/.gitignore +137 -0
  703. nautobot/ui/.node-version +1 -0
  704. nautobot/ui/.prettierignore +3 -0
  705. nautobot/ui/eslint.config.js +33 -0
  706. nautobot/ui/package-lock.json +6594 -0
  707. nautobot/ui/package.json +67 -0
  708. nautobot/ui/prettier.config.js +9 -0
  709. nautobot/ui/src/js/collapse.js +69 -0
  710. nautobot/ui/src/js/cookie.js +31 -0
  711. nautobot/ui/src/js/draggable.js +101 -0
  712. nautobot/ui/src/js/drawer.js +106 -0
  713. nautobot/ui/src/js/form.js +23 -0
  714. nautobot/ui/src/js/history.js +51 -0
  715. nautobot/ui/src/js/nautobot-graphiql.js +19 -0
  716. nautobot/ui/src/js/nautobot.js +128 -0
  717. nautobot/ui/src/js/search.js +274 -0
  718. nautobot/ui/src/js/select2.js +318 -0
  719. nautobot/ui/src/js/sidenav.js +87 -0
  720. nautobot/ui/src/js/tabs.js +139 -0
  721. nautobot/ui/src/js/theme.js +104 -0
  722. nautobot/ui/src/js/utils.js +54 -0
  723. nautobot/ui/src/scss/colors.scss +58 -0
  724. nautobot/ui/src/scss/nautobot.scss +2471 -0
  725. nautobot/ui/webpack.config.js +148 -0
  726. nautobot/users/apps.py +3 -0
  727. nautobot/users/filters.py +7 -11
  728. nautobot/users/forms.py +10 -0
  729. nautobot/users/models.py +8 -0
  730. nautobot/users/templates/users/advanced_settings_edit.html +31 -21
  731. nautobot/users/templates/users/api_tokens.html +61 -51
  732. nautobot/users/templates/users/base.html +23 -31
  733. nautobot/users/templates/users/change_password.html +29 -19
  734. nautobot/users/templates/users/preferences.html +55 -45
  735. nautobot/users/templates/users/profile.html +45 -14
  736. nautobot/users/tests/test_api.py +4 -0
  737. nautobot/users/urls.py +2 -0
  738. nautobot/users/views.py +70 -2
  739. nautobot/virtualization/api/views.py +1 -1
  740. nautobot/virtualization/filters.py +18 -32
  741. nautobot/virtualization/forms.py +22 -59
  742. nautobot/virtualization/models.py +1 -19
  743. nautobot/virtualization/navigation.py +3 -1
  744. nautobot/virtualization/tables.py +10 -6
  745. nautobot/virtualization/templates/virtualization/cluster.html +13 -13
  746. nautobot/virtualization/templates/virtualization/cluster_edit.html +6 -6
  747. nautobot/virtualization/templates/virtualization/inc/virtualmachine_vminterface_filter.html +1 -1
  748. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  749. nautobot/virtualization/templates/virtualization/virtualmachine_component_add.html +24 -16
  750. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +1 -1
  751. nautobot/virtualization/templates/virtualization/virtualmachine_list.html +4 -4
  752. nautobot/virtualization/templates/virtualization/virtualmachine_update.html +27 -25
  753. nautobot/virtualization/templates/virtualization/vminterface.html +5 -5
  754. nautobot/virtualization/templates/virtualization/vminterface_edit.html +27 -11
  755. nautobot/virtualization/tests/test_api.py +3 -0
  756. nautobot/virtualization/tests/test_models.py +20 -5
  757. nautobot/virtualization/tests/test_views.py +3 -5
  758. nautobot/virtualization/urls.py +0 -11
  759. nautobot/virtualization/views.py +5 -122
  760. nautobot/vpn/__init__.py +0 -0
  761. nautobot/vpn/api/serializers.py +113 -0
  762. nautobot/vpn/api/urls.py +19 -0
  763. nautobot/vpn/api/views.py +70 -0
  764. nautobot/vpn/apps.py +8 -0
  765. nautobot/vpn/choices.py +171 -0
  766. nautobot/vpn/factory.py +209 -0
  767. nautobot/vpn/filters.py +233 -0
  768. nautobot/vpn/forms.py +486 -0
  769. nautobot/vpn/homepage.py +19 -0
  770. nautobot/vpn/migrations/0001_initial.py +541 -0
  771. nautobot/vpn/migrations/0002_populate_defaults.py +199 -0
  772. nautobot/vpn/migrations/__init__.py +0 -0
  773. nautobot/vpn/models.py +527 -0
  774. nautobot/vpn/navigation.py +98 -0
  775. nautobot/vpn/tables.py +380 -0
  776. nautobot/vpn/templates/vpn/vpnprofile.html +2 -0
  777. nautobot/vpn/templates/vpn/vpnprofile_create.html +150 -0
  778. nautobot/vpn/tests/__init__.py +0 -0
  779. nautobot/vpn/tests/test_api.py +341 -0
  780. nautobot/vpn/tests/test_filters.py +139 -0
  781. nautobot/vpn/tests/test_forms.py +294 -0
  782. nautobot/vpn/tests/test_models.py +97 -0
  783. nautobot/vpn/tests/test_views.py +281 -0
  784. nautobot/vpn/urls.py +16 -0
  785. nautobot/vpn/views.py +437 -0
  786. nautobot/wireless/filters.py +0 -8
  787. nautobot/wireless/navigation.py +3 -1
  788. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +6 -6
  789. nautobot/wireless/tests/integration/test_radio_profile.py +3 -7
  790. nautobot/wireless/tests/test_api.py +1 -1
  791. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/METADATA +5 -4
  792. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/RECORD +802 -707
  793. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/entry_points.txt +1 -0
  794. nautobot/core/management/commands/check_job_approval_status.py +0 -47
  795. nautobot/core/templates/search_form.html +0 -9
  796. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +0 -87
  797. nautobot/dcim/filters/mixins.py +0 -354
  798. nautobot/extras/templates/extras/job_approval_request.html +0 -134
  799. nautobot/extras/templates/extras/scheduled_jobs_approval_queue_list.html +0 -28
  800. nautobot/ipam/mixins.py +0 -32
  801. nautobot/ipam/templates/ipam/inc/prefix_header_extra_content_table.html +0 -4
  802. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +0 -587
  803. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +0 -1
  804. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +0 -6
  805. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +0 -1
  806. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +0 -6865
  807. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +0 -1
  808. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +0 -6
  809. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +0 -1
  810. nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.eot +0 -0
  811. nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.svg +0 -288
  812. nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  813. nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff +0 -0
  814. nautobot/project-static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  815. nautobot/project-static/bootstrap-3.4.1-dist/js/bootstrap.js +0 -2580
  816. nautobot/project-static/bootstrap-3.4.1-dist/js/bootstrap.min.js +0 -6
  817. nautobot/project-static/bootstrap-3.4.1-dist/js/npm.js +0 -13
  818. nautobot/project-static/clipboard.js-2.0.9/clipboard.min.js +0 -7
  819. nautobot/project-static/css/base.css +0 -1040
  820. nautobot/project-static/css/dark.css +0 -282
  821. nautobot/project-static/flatpickr-4.6.9/flatpickr.min.js +0 -2
  822. nautobot/project-static/flatpickr-4.6.9/themes/light.min.css +0 -1
  823. nautobot/project-static/graphiql-1.5.16/graphiql.min.css +0 -12
  824. nautobot/project-static/graphiql-1.5.16/graphiql.min.js +0 -11
  825. nautobot/project-static/highlight.js-11.9.0/github-dark.min.css +0 -10
  826. nautobot/project-static/highlight.js-11.9.0/github.min.css +0 -10
  827. nautobot/project-static/highlight.js-11.9.0/highlight.min.js +0 -378
  828. nautobot/project-static/jquery/jquery-3.7.1.min.js +0 -2
  829. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_444444_256x240.png +0 -0
  830. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_555555_256x240.png +0 -0
  831. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_777620_256x240.png +0 -0
  832. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_777777_256x240.png +0 -0
  833. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_cc0000_256x240.png +0 -0
  834. nautobot/project-static/jquery-ui-1.13.2/images/ui-icons_ffffff_256x240.png +0 -0
  835. nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.css +0 -7
  836. nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.js +0 -6
  837. nautobot/project-static/jquery-ui-1.13.2/jquery-ui.structure.min.css +0 -5
  838. nautobot/project-static/jquery-ui-1.13.2/jquery-ui.theme.min.css +0 -5
  839. nautobot/project-static/js/homepage_layout.js +0 -182
  840. nautobot/project-static/js/nav_menu.js +0 -250
  841. nautobot/project-static/js/theme.js +0 -133
  842. nautobot/project-static/materialdesignicons-7.4.47/LICENSE +0 -20
  843. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +0 -3
  844. nautobot/project-static/react-16.14.0/react.production.min.js +0 -32
  845. nautobot/project-static/react-dom-16.14.0/react-dom.production.min.js +0 -239
  846. nautobot/project-static/select2-4.0.13/i18n/af.js +0 -3
  847. nautobot/project-static/select2-4.0.13/i18n/ar.js +0 -3
  848. nautobot/project-static/select2-4.0.13/i18n/az.js +0 -3
  849. nautobot/project-static/select2-4.0.13/i18n/bg.js +0 -3
  850. nautobot/project-static/select2-4.0.13/i18n/bn.js +0 -3
  851. nautobot/project-static/select2-4.0.13/i18n/bs.js +0 -3
  852. nautobot/project-static/select2-4.0.13/i18n/ca.js +0 -3
  853. nautobot/project-static/select2-4.0.13/i18n/cs.js +0 -3
  854. nautobot/project-static/select2-4.0.13/i18n/da.js +0 -3
  855. nautobot/project-static/select2-4.0.13/i18n/de.js +0 -3
  856. nautobot/project-static/select2-4.0.13/i18n/dsb.js +0 -3
  857. nautobot/project-static/select2-4.0.13/i18n/el.js +0 -3
  858. nautobot/project-static/select2-4.0.13/i18n/en.js +0 -3
  859. nautobot/project-static/select2-4.0.13/i18n/es.js +0 -3
  860. nautobot/project-static/select2-4.0.13/i18n/et.js +0 -3
  861. nautobot/project-static/select2-4.0.13/i18n/eu.js +0 -3
  862. nautobot/project-static/select2-4.0.13/i18n/fa.js +0 -3
  863. nautobot/project-static/select2-4.0.13/i18n/fi.js +0 -3
  864. nautobot/project-static/select2-4.0.13/i18n/fr.js +0 -3
  865. nautobot/project-static/select2-4.0.13/i18n/gl.js +0 -3
  866. nautobot/project-static/select2-4.0.13/i18n/he.js +0 -3
  867. nautobot/project-static/select2-4.0.13/i18n/hi.js +0 -3
  868. nautobot/project-static/select2-4.0.13/i18n/hr.js +0 -3
  869. nautobot/project-static/select2-4.0.13/i18n/hsb.js +0 -3
  870. nautobot/project-static/select2-4.0.13/i18n/hu.js +0 -3
  871. nautobot/project-static/select2-4.0.13/i18n/hy.js +0 -3
  872. nautobot/project-static/select2-4.0.13/i18n/id.js +0 -3
  873. nautobot/project-static/select2-4.0.13/i18n/is.js +0 -3
  874. nautobot/project-static/select2-4.0.13/i18n/it.js +0 -3
  875. nautobot/project-static/select2-4.0.13/i18n/ja.js +0 -3
  876. nautobot/project-static/select2-4.0.13/i18n/ka.js +0 -3
  877. nautobot/project-static/select2-4.0.13/i18n/km.js +0 -3
  878. nautobot/project-static/select2-4.0.13/i18n/ko.js +0 -3
  879. nautobot/project-static/select2-4.0.13/i18n/lt.js +0 -3
  880. nautobot/project-static/select2-4.0.13/i18n/lv.js +0 -3
  881. nautobot/project-static/select2-4.0.13/i18n/mk.js +0 -3
  882. nautobot/project-static/select2-4.0.13/i18n/ms.js +0 -3
  883. nautobot/project-static/select2-4.0.13/i18n/nb.js +0 -3
  884. nautobot/project-static/select2-4.0.13/i18n/ne.js +0 -3
  885. nautobot/project-static/select2-4.0.13/i18n/nl.js +0 -3
  886. nautobot/project-static/select2-4.0.13/i18n/pl.js +0 -3
  887. nautobot/project-static/select2-4.0.13/i18n/ps.js +0 -3
  888. nautobot/project-static/select2-4.0.13/i18n/pt-BR.js +0 -3
  889. nautobot/project-static/select2-4.0.13/i18n/pt.js +0 -3
  890. nautobot/project-static/select2-4.0.13/i18n/ro.js +0 -3
  891. nautobot/project-static/select2-4.0.13/i18n/ru.js +0 -3
  892. nautobot/project-static/select2-4.0.13/i18n/sk.js +0 -3
  893. nautobot/project-static/select2-4.0.13/i18n/sl.js +0 -3
  894. nautobot/project-static/select2-4.0.13/i18n/sq.js +0 -3
  895. nautobot/project-static/select2-4.0.13/i18n/sr-Cyrl.js +0 -3
  896. nautobot/project-static/select2-4.0.13/i18n/sr.js +0 -3
  897. nautobot/project-static/select2-4.0.13/i18n/sv.js +0 -3
  898. nautobot/project-static/select2-4.0.13/i18n/th.js +0 -3
  899. nautobot/project-static/select2-4.0.13/i18n/tk.js +0 -3
  900. nautobot/project-static/select2-4.0.13/i18n/tr.js +0 -3
  901. nautobot/project-static/select2-4.0.13/i18n/uk.js +0 -3
  902. nautobot/project-static/select2-4.0.13/i18n/vi.js +0 -3
  903. nautobot/project-static/select2-4.0.13/i18n/zh-CN.js +0 -3
  904. nautobot/project-static/select2-4.0.13/i18n/zh-TW.js +0 -3
  905. nautobot/project-static/select2-4.0.13/select2.min.css +0 -1
  906. nautobot/project-static/select2-4.0.13/select2.min.js +0 -2
  907. nautobot/project-static/select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css +0 -7
  908. nautobot/project-static/subscriptions-transport-ws-0.9.18/client.min.js +0 -8
  909. nautobot/project-static/whatwg-fetch-3.6.2/fetch.umd.min.js +0 -8
  910. nautobot/virtualization/templates/virtualization/cluster_add_devices.html +0 -37
  911. /nautobot/extras/{filters/customfields.py → filter_mixins_customfields.py} +0 -0
  912. /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.ttf → dist/1fcc36272ea3e53d0031.ttf} +0 -0
  913. /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.eot → dist/2146c3c82b553977abc7.eot} +0 -0
  914. /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff → dist/e55a20c80650829ec5fd.woff} +0 -0
  915. /nautobot/project-static/{materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 → dist/ec024da790d2972da002.woff2} +0 -0
  916. /nautobot/tenancy/{filters/mixins.py → filter_mixins.py} +0 -0
  917. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/LICENSE.txt +0 -0
  918. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/NOTICE +0 -0
  919. {nautobot-2.4.21.dist-info → nautobot-3.0.0a3.dist-info}/WHEEL +0 -0
@@ -7,6 +7,7 @@ from timezone_field import TimeZoneField
7
7
  from nautobot.core.filters import (
8
8
  BaseFilterSet,
9
9
  ContentTypeMultipleChoiceFilter,
10
+ ModelMultipleChoiceFilter,
10
11
  MultiValueCharFilter,
11
12
  MultiValueMACAddressFilter,
12
13
  MultiValueUUIDFilter,
@@ -17,7 +18,6 @@ from nautobot.core.filters import (
17
18
  TreeNodeMultipleChoiceFilter,
18
19
  )
19
20
  from nautobot.core.utils.data import is_uuid
20
- from nautobot.core.utils.deprecation import class_deprecated_in_favor_of
21
21
  from nautobot.dcim.choices import (
22
22
  CableTypeChoices,
23
23
  ConsolePortTypeChoices,
@@ -34,7 +34,7 @@ from nautobot.dcim.constants import (
34
34
  VIRTUAL_IFACE_TYPES,
35
35
  WIRELESS_IFACE_TYPES,
36
36
  )
37
- from nautobot.dcim.filters.mixins import (
37
+ from nautobot.dcim.filter_mixins import (
38
38
  CableTerminationModelFilterSetMixin,
39
39
  DeviceComponentModelFilterSetMixin,
40
40
  DeviceComponentTemplateModelFilterSetMixin,
@@ -56,6 +56,7 @@ from nautobot.dcim.models import (
56
56
  Device,
57
57
  DeviceBay,
58
58
  DeviceBayTemplate,
59
+ DeviceClusterAssignment,
59
60
  DeviceFamily,
60
61
  DeviceRedundancyGroup,
61
62
  DeviceType,
@@ -102,14 +103,13 @@ from nautobot.extras.filters import (
102
103
  from nautobot.extras.models import ExternalIntegration, SecretsGroup
103
104
  from nautobot.extras.utils import FeatureQuery
104
105
  from nautobot.ipam.models import IPAddress, VLAN, VLANGroup
105
- from nautobot.tenancy.filters.mixins import TenancyModelFilterSetMixin
106
+ from nautobot.tenancy.filter_mixins import TenancyModelFilterSetMixin
106
107
  from nautobot.tenancy.models import Tenant
107
108
  from nautobot.virtualization.models import Cluster, VirtualMachine
108
109
  from nautobot.wireless.models import RadioProfile, WirelessNetwork
109
110
 
110
111
  __all__ = (
111
112
  "CableFilterSet",
112
- "CableTerminationFilterSet",
113
113
  "CableTerminationModelFilterSetMixin",
114
114
  "ConsoleConnectionFilterSet",
115
115
  "ConsolePortFilterSet",
@@ -120,6 +120,7 @@ __all__ = (
120
120
  "ControllerManagedDeviceGroupFilterSet",
121
121
  "DeviceBayFilterSet",
122
122
  "DeviceBayTemplateFilterSet",
123
+ "DeviceClusterAssignmentFilterSet",
123
124
  "DeviceFamilyFilterSet",
124
125
  "DeviceFilterSet",
125
126
  "DeviceRedundancyGroupFilterSet",
@@ -132,6 +133,7 @@ __all__ = (
132
133
  "InterfaceRedundancyGroupAssociationFilterSet",
133
134
  "InterfaceRedundancyGroupFilterSet",
134
135
  "InterfaceTemplateFilterSet",
136
+ "InterfaceVDCAssignmentFilterSet",
135
137
  "InventoryItemFilterSet",
136
138
  "LocationFilterSet",
137
139
  "LocationTypeFilterSet",
@@ -141,7 +143,6 @@ __all__ = (
141
143
  "ModuleFamilyFilterSet",
142
144
  "ModuleFilterSet",
143
145
  "ModuleTypeFilterSet",
144
- "PathEndpointFilterSet",
145
146
  "PathEndpointModelFilterSetMixin",
146
147
  "PlatformFilterSet",
147
148
  "PowerConnectionFilterSet",
@@ -198,7 +199,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
198
199
  location_type = NaturalKeyOrPKMultipleChoiceFilter(
199
200
  queryset=LocationType.objects.all(),
200
201
  to_field_name="name",
201
- label="Location type (name or ID)",
202
202
  )
203
203
  parent = NaturalKeyOrPKMultipleChoiceFilter(
204
204
  prefers_id=True,
@@ -231,7 +231,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
231
231
  prefers_id=True,
232
232
  queryset=Device.objects.all(),
233
233
  to_field_name="name",
234
- label="Devices (name or ID)",
235
234
  )
236
235
  has_devices = RelatedMembershipBooleanFilter(
237
236
  field_name="devices",
@@ -240,7 +239,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
240
239
  power_panels = NaturalKeyOrPKMultipleChoiceFilter(
241
240
  to_field_name="name",
242
241
  queryset=PowerPanel.objects.all(),
243
- label="Power panels (name or ID)",
244
242
  )
245
243
  has_power_panels = RelatedMembershipBooleanFilter(
246
244
  field_name="power_panels",
@@ -250,7 +248,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
250
248
  prefers_id=True,
251
249
  queryset=RackGroup.objects.all(),
252
250
  to_field_name="name",
253
- label="Rack groups (name or ID)",
254
251
  )
255
252
  has_rack_groups = RelatedMembershipBooleanFilter(
256
253
  field_name="rack_groups",
@@ -263,7 +260,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
263
260
  racks = NaturalKeyOrPKMultipleChoiceFilter(
264
261
  queryset=Rack.objects.all(),
265
262
  to_field_name="name",
266
- label="Rack (name or ID)",
267
263
  )
268
264
  has_prefixes = RelatedMembershipBooleanFilter(
269
265
  field_name="prefixes",
@@ -295,7 +291,6 @@ class LocationFilterSet(NautobotFilterSet, StatusModelFilterSetMixin, TenancyMod
295
291
  clusters = NaturalKeyOrPKMultipleChoiceFilter(
296
292
  queryset=Cluster.objects.all(),
297
293
  to_field_name="name",
298
- label="Clusters (name or ID)",
299
294
  )
300
295
  time_zone = django_filters.MultipleChoiceFilter(
301
296
  choices=[(str(obj), name) for obj, name in TimeZoneField().choices],
@@ -362,7 +357,6 @@ class RackGroupFilterSet(LocatableModelFilterSetMixin, NautobotFilterSet, NameSe
362
357
  parent = NaturalKeyOrPKMultipleChoiceFilter(
363
358
  queryset=RackGroup.objects.all(),
364
359
  to_field_name="name",
365
- label="Parent (name or ID)",
366
360
  )
367
361
  ancestors = NaturalKeyOrPKMultipleChoiceFilter(
368
362
  queryset=Location.objects.all(),
@@ -373,7 +367,6 @@ class RackGroupFilterSet(LocatableModelFilterSetMixin, NautobotFilterSet, NameSe
373
367
  children = NaturalKeyOrPKMultipleChoiceFilter(
374
368
  queryset=RackGroup.objects.all(),
375
369
  to_field_name="name",
376
- label="Children (name or ID)",
377
370
  )
378
371
  has_children = RelatedMembershipBooleanFilter(
379
372
  field_name="children",
@@ -385,7 +378,6 @@ class RackGroupFilterSet(LocatableModelFilterSetMixin, NautobotFilterSet, NameSe
385
378
  field_name="power_panels",
386
379
  to_field_name="name",
387
380
  queryset=PowerPanel.objects.all(),
388
- label="Power panels (name or ID)",
389
381
  )
390
382
  has_power_panels = RelatedMembershipBooleanFilter(
391
383
  field_name="power_panels",
@@ -463,7 +455,6 @@ class RackFilterSet(
463
455
  field_name="power_feeds",
464
456
  to_field_name="name",
465
457
  queryset=PowerFeed.objects.all(),
466
- label="Power feeds (name or ID)",
467
458
  )
468
459
  has_power_feeds = RelatedMembershipBooleanFilter(
469
460
  field_name="power_feeds",
@@ -512,14 +503,12 @@ class RackReservationFilterSet(TenancyModelFilterSetMixin, NautobotFilterSet):
512
503
  user = NaturalKeyOrPKMultipleChoiceFilter(
513
504
  queryset=get_user_model().objects.all(),
514
505
  to_field_name="username",
515
- label="User (username or ID)",
516
506
  )
517
507
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
518
508
  rack = NaturalKeyOrPKMultipleChoiceFilter(
519
509
  prefers_id=True,
520
510
  queryset=Rack.objects.all(),
521
511
  to_field_name="name",
522
- label="Rack (name or ID)",
523
512
  )
524
513
 
525
514
  class Meta:
@@ -533,7 +522,6 @@ class ManufacturerFilterSet(NautobotFilterSet, NameSearchFilterSet):
533
522
  prefers_id=True,
534
523
  queryset=InventoryItem.objects.all(),
535
524
  to_field_name="name",
536
- label="Inventory items (name or ID)",
537
525
  )
538
526
  has_inventory_items = RelatedMembershipBooleanFilter(
539
527
  field_name="inventory_items",
@@ -542,7 +530,6 @@ class ManufacturerFilterSet(NautobotFilterSet, NameSearchFilterSet):
542
530
  device_types = NaturalKeyOrPKMultipleChoiceFilter(
543
531
  queryset=DeviceType.objects.all(),
544
532
  to_field_name="model",
545
- label="Device types (model or ID)",
546
533
  )
547
534
  has_device_types = RelatedMembershipBooleanFilter(
548
535
  field_name="device_types",
@@ -551,7 +538,6 @@ class ManufacturerFilterSet(NautobotFilterSet, NameSearchFilterSet):
551
538
  platforms = NaturalKeyOrPKMultipleChoiceFilter(
552
539
  queryset=Platform.objects.all(),
553
540
  to_field_name="name",
554
- label="Platforms (name or ID)",
555
541
  )
556
542
  has_platforms = RelatedMembershipBooleanFilter(
557
543
  field_name="platforms",
@@ -567,7 +553,6 @@ class DeviceFamilyFilterSet(NautobotFilterSet, NameSearchFilterSet):
567
553
  device_types = NaturalKeyOrPKMultipleChoiceFilter(
568
554
  queryset=DeviceType.objects.all(),
569
555
  to_field_name="model",
570
- label="Device types (model or ID)",
571
556
  )
572
557
  has_device_types = RelatedMembershipBooleanFilter(
573
558
  field_name="device_types",
@@ -590,7 +575,8 @@ class DeviceTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
590
575
  },
591
576
  )
592
577
  device_family = NaturalKeyOrPKMultipleChoiceFilter(
593
- queryset=DeviceFamily.objects.all(), to_field_name="name", label="Device family (name or ID)"
578
+ queryset=DeviceFamily.objects.all(),
579
+ to_field_name="name",
594
580
  )
595
581
  console_ports = django_filters.BooleanFilter(
596
582
  method="_console_ports",
@@ -629,7 +615,6 @@ class DeviceTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
629
615
  prefers_id=True,
630
616
  to_field_name="name",
631
617
  queryset=DeviceBayTemplate.objects.all(),
632
- label="Device bay templates (name or ID)",
633
618
  )
634
619
  has_device_bay_templates = RelatedMembershipBooleanFilter(
635
620
  field_name="device_bay_templates",
@@ -642,7 +627,6 @@ class DeviceTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
642
627
  software_image_files = NaturalKeyOrPKMultipleChoiceFilter(
643
628
  queryset=SoftwareImageFile.objects.all(),
644
629
  to_field_name="image_file_name",
645
- label="Software image files (image file name or ID)",
646
630
  )
647
631
 
648
632
  class Meta:
@@ -680,12 +664,6 @@ class DeviceTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
680
664
  return queryset.exclude(device_bay_templates__isnull=value)
681
665
 
682
666
 
683
- # TODO: remove in 2.2
684
- @class_deprecated_in_favor_of(DeviceComponentTemplateModelFilterSetMixin)
685
- class DeviceTypeComponentFilterSet(DeviceComponentTemplateModelFilterSetMixin):
686
- pass
687
-
688
-
689
667
  class ConsolePortTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMixin, BaseFilterSet):
690
668
  class Meta:
691
669
  model = ConsolePortTemplate
@@ -704,7 +682,6 @@ class PowerPortTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMix
704
682
  prefers_id=True,
705
683
  to_field_name="name",
706
684
  queryset=PowerOutletTemplate.objects.all(),
707
- label="Power outlet templates (name or ID)",
708
685
  )
709
686
  has_power_outlet_templates = RelatedMembershipBooleanFilter(
710
687
  field_name="power_outlet_templates",
@@ -726,7 +703,6 @@ class PowerOutletTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetM
726
703
  prefers_id=True,
727
704
  to_field_name="name",
728
705
  queryset=PowerPortTemplate.objects.all(),
729
- label="Power port template (name or ID)",
730
706
  )
731
707
 
732
708
  class Meta:
@@ -741,21 +717,12 @@ class InterfaceTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMix
741
717
 
742
718
 
743
719
  class FrontPortTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMixin, BaseFilterSet):
744
- rear_port_template = django_filters.ModelMultipleChoiceFilter(
745
- queryset=RearPortTemplate.objects.all(),
746
- label="Rear port template",
747
- )
748
-
749
720
  class Meta:
750
721
  model = FrontPortTemplate
751
- fields = ["type", "rear_port_position"]
722
+ fields = ["type", "rear_port_position", "rear_port_template"]
752
723
 
753
724
 
754
725
  class RearPortTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMixin, BaseFilterSet):
755
- front_port_templates = django_filters.ModelMultipleChoiceFilter(
756
- queryset=FrontPortTemplate.objects.all(),
757
- label="Front port templates",
758
- )
759
726
  has_front_port_templates = RelatedMembershipBooleanFilter(
760
727
  field_name="front_port_templates",
761
728
  label="Has front port templates",
@@ -763,7 +730,7 @@ class RearPortTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMixi
763
730
 
764
731
  class Meta:
765
732
  model = RearPortTemplate
766
- fields = ["type", "positions"]
733
+ fields = ["type", "positions", "front_port_templates"]
767
734
 
768
735
 
769
736
  class DeviceBayTemplateFilterSet(DeviceComponentTemplateModelFilterSetMixin, BaseFilterSet):
@@ -774,7 +741,8 @@ class DeviceBayTemplateFilterSet(DeviceComponentTemplateModelFilterSetMixin, Bas
774
741
 
775
742
  class PlatformFilterSet(NautobotFilterSet, NameSearchFilterSet):
776
743
  manufacturer = NaturalKeyOrPKMultipleChoiceFilter(
777
- queryset=Manufacturer.objects.all(), to_field_name="name", label="Manufacturer (name or ID)"
744
+ queryset=Manufacturer.objects.all(),
745
+ to_field_name="name",
778
746
  )
779
747
  has_devices = RelatedMembershipBooleanFilter(
780
748
  field_name="devices",
@@ -849,10 +817,10 @@ class DeviceFilterSet(
849
817
  device_type = NaturalKeyOrPKMultipleChoiceFilter(
850
818
  queryset=DeviceType.objects.all(),
851
819
  to_field_name="model",
852
- label="Device type (model or ID)",
853
820
  )
854
821
  platform = NaturalKeyOrPKMultipleChoiceFilter(
855
- queryset=Platform.objects.all(), to_field_name="name", label="Platform (name or ID)"
822
+ queryset=Platform.objects.all(),
823
+ to_field_name="name",
856
824
  )
857
825
  rack_group = TreeNodeMultipleChoiceFilter(
858
826
  prefers_id=True,
@@ -866,13 +834,20 @@ class DeviceFilterSet(
866
834
  prefers_id=True,
867
835
  queryset=Rack.objects.all(),
868
836
  to_field_name="name",
869
- label="Rack (name or ID)",
870
837
  )
838
+ # TODO: This is deprecated, left for backwards compatibility.
871
839
  cluster = NaturalKeyOrPKMultipleChoiceFilter(
840
+ field_name="clusters",
872
841
  queryset=Cluster.objects.all(),
873
842
  to_field_name="name",
874
843
  label="VM cluster (name or ID)",
875
844
  )
845
+ clusters = NaturalKeyOrPKMultipleChoiceFilter(
846
+ field_name="clusters",
847
+ queryset=Cluster.objects.all(),
848
+ to_field_name="name",
849
+ label="VM clusters (name or ID)",
850
+ )
876
851
  is_full_depth = django_filters.BooleanFilter(
877
852
  field_name="device_type__is_full_depth",
878
853
  label="Is full depth",
@@ -885,12 +860,10 @@ class DeviceFilterSet(
885
860
  secrets_group = NaturalKeyOrPKMultipleChoiceFilter(
886
861
  queryset=SecretsGroup.objects.all(),
887
862
  to_field_name="name",
888
- label="Secrets group (name or ID)",
889
863
  )
890
864
  virtual_chassis = NaturalKeyOrPKMultipleChoiceFilter(
891
865
  queryset=VirtualChassis.objects.all(),
892
866
  to_field_name="name",
893
- label="Virtual chassis (name or ID)",
894
867
  )
895
868
  is_virtual_chassis_member = RelatedMembershipBooleanFilter(
896
869
  field_name="virtual_chassis",
@@ -900,23 +873,17 @@ class DeviceFilterSet(
900
873
  field_name="device_redundancy_group",
901
874
  queryset=DeviceRedundancyGroup.objects.all(),
902
875
  to_field_name="name",
903
- label="Device Redundancy Groups (name or ID)",
904
876
  )
905
877
  controller_managed_device_group = NaturalKeyOrPKMultipleChoiceFilter(
906
878
  field_name="controller_managed_device_group",
907
879
  queryset=ControllerManagedDeviceGroup.objects.all(),
908
880
  to_field_name="name",
909
- label="Controller Managed Device Groups (name or ID)",
910
881
  )
911
882
  virtual_chassis_member = is_virtual_chassis_member
912
883
  has_device_bays = RelatedMembershipBooleanFilter(
913
884
  field_name="device_bays",
914
885
  label="Has device bays",
915
886
  )
916
- device_bays = django_filters.ModelMultipleChoiceFilter(
917
- queryset=DeviceBay.objects.all(),
918
- label="Device Bays",
919
- )
920
887
  has_software_image_files = RelatedMembershipBooleanFilter(
921
888
  field_name="software_image_files",
922
889
  label="Has software image files",
@@ -924,7 +891,6 @@ class DeviceFilterSet(
924
891
  software_image_files = NaturalKeyOrPKMultipleChoiceFilter(
925
892
  queryset=SoftwareImageFile.objects.all(),
926
893
  to_field_name="image_file_name",
927
- label="Software image files (image file name or ID)",
928
894
  )
929
895
  has_software_version = RelatedMembershipBooleanFilter(
930
896
  field_name="software_version",
@@ -933,7 +899,6 @@ class DeviceFilterSet(
933
899
  software_version = NaturalKeyOrPKMultipleChoiceFilter(
934
900
  queryset=SoftwareVersion.objects.all(),
935
901
  to_field_name="version",
936
- label="Software version (version or ID)",
937
902
  )
938
903
  ip_addresses = MultiValueCharFilter(
939
904
  method="filter_ip_addresses",
@@ -945,7 +910,6 @@ class DeviceFilterSet(
945
910
  field_name="controller_managed_device_group__radio_profiles",
946
911
  queryset=RadioProfile.objects.all(),
947
912
  to_field_name="name",
948
- label="Radio Profiles (name or ID)",
949
913
  )
950
914
  has_radio_profiles = RelatedMembershipBooleanFilter(
951
915
  field_name="controller_managed_device_group__radio_profiles",
@@ -955,7 +919,6 @@ class DeviceFilterSet(
955
919
  field_name="controller_managed_device_group__wireless_networks",
956
920
  queryset=WirelessNetwork.objects.all(),
957
921
  to_field_name="name",
958
- label="Wireless Networks (name or ID)",
959
922
  )
960
923
  has_wireless_networks = RelatedMembershipBooleanFilter(
961
924
  field_name="controller_managed_device_group__wireless_networks",
@@ -987,6 +950,7 @@ class DeviceFilterSet(
987
950
  "vc_priority",
988
951
  "device_redundancy_group_priority",
989
952
  "tags",
953
+ "device_bays",
990
954
  "interfaces",
991
955
  "has_software_image_files",
992
956
  "software_image_files",
@@ -1005,24 +969,6 @@ class DeviceFilterSet(
1005
969
  return queryset.filter(params)
1006
970
 
1007
971
 
1008
- # TODO: remove in 2.2
1009
- @class_deprecated_in_favor_of(DeviceComponentModelFilterSetMixin)
1010
- class DeviceComponentFilterSet(DeviceComponentModelFilterSetMixin):
1011
- pass
1012
-
1013
-
1014
- # TODO: remove in 2.2
1015
- @class_deprecated_in_favor_of(CableTerminationModelFilterSetMixin)
1016
- class CableTerminationFilterSet(CableTerminationModelFilterSetMixin):
1017
- pass
1018
-
1019
-
1020
- # TODO: remove in 2.2
1021
- @class_deprecated_in_favor_of(PathEndpointModelFilterSetMixin)
1022
- class PathEndpointFilterSet(PathEndpointModelFilterSetMixin):
1023
- pass
1024
-
1025
-
1026
972
  class ConsolePortFilterSet(
1027
973
  ModularDeviceComponentModelFilterSetMixin,
1028
974
  CableTerminationModelFilterSetMixin,
@@ -1062,7 +1008,6 @@ class PowerPortFilterSet(
1062
1008
  field_name="power_outlets",
1063
1009
  to_field_name="name",
1064
1010
  queryset=PowerOutlet.objects.all(),
1065
- label="Power outlets (name or ID)",
1066
1011
  )
1067
1012
  has_power_outlets = RelatedMembershipBooleanFilter(
1068
1013
  field_name="power_outlets",
@@ -1081,14 +1026,10 @@ class PowerOutletFilterSet(
1081
1026
  BaseFilterSet,
1082
1027
  ):
1083
1028
  type = django_filters.MultipleChoiceFilter(choices=PowerOutletTypeChoices, null_value=None)
1084
- power_port = django_filters.ModelMultipleChoiceFilter(
1085
- queryset=PowerPort.objects.all(),
1086
- label="Power port",
1087
- )
1088
1029
 
1089
1030
  class Meta:
1090
1031
  model = PowerOutlet
1091
- fields = ["id", "name", "feed_leg", "description", "label", "tags"]
1032
+ fields = ["id", "name", "feed_leg", "power_port", "description", "label", "tags"]
1092
1033
 
1093
1034
 
1094
1035
  class InterfaceFilterSet(
@@ -1104,11 +1045,10 @@ class InterfaceFilterSet(
1104
1045
  device = NaturalKeyOrPKMultipleChoiceFilter(
1105
1046
  queryset=Device.objects.all(),
1106
1047
  to_field_name="name",
1107
- label="Device (name or ID)",
1108
1048
  method="filter_device",
1109
1049
  )
1110
1050
  # TODO 3.0: Remove this filter. Deprecated in favor of above NaturalKeyOrPKMultipleChoiceFilter `device`
1111
- device_id = django_filters.ModelMultipleChoiceFilter(
1051
+ device_id = ModelMultipleChoiceFilter(
1112
1052
  queryset=Device.objects.all(),
1113
1053
  method="filter_device_id",
1114
1054
  field_name="device",
@@ -1128,33 +1068,28 @@ class InterfaceFilterSet(
1128
1068
  prefers_id=True,
1129
1069
  queryset=Interface.objects.all(),
1130
1070
  to_field_name="name",
1131
- label="Parent interface (name or ID)",
1132
1071
  )
1133
1072
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
1134
1073
  bridge = NaturalKeyOrPKMultipleChoiceFilter(
1135
1074
  prefers_id=True,
1136
1075
  queryset=Interface.objects.all(),
1137
1076
  to_field_name="name",
1138
- label="Bridge interface (name or ID)",
1139
1077
  )
1140
1078
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
1141
1079
  lag = NaturalKeyOrPKMultipleChoiceFilter(
1142
1080
  prefers_id=True,
1143
1081
  to_field_name="name",
1144
1082
  queryset=Interface.objects.filter(type=InterfaceTypeChoices.TYPE_LAG),
1145
- label="LAG interface (name or ID)",
1146
1083
  )
1147
1084
  untagged_vlan = NaturalKeyOrPKMultipleChoiceFilter(
1148
1085
  prefers_id=True,
1149
1086
  to_field_name="vid",
1150
1087
  queryset=VLAN.objects.all(),
1151
- label="Untagged VLAN (VID or ID)",
1152
1088
  )
1153
1089
  tagged_vlans = NaturalKeyOrPKMultipleChoiceFilter(
1154
1090
  prefers_id=True,
1155
1091
  to_field_name="vid",
1156
1092
  queryset=VLAN.objects.all(),
1157
- label="Tagged VLANs (VID or ID)",
1158
1093
  )
1159
1094
  has_tagged_vlans = RelatedMembershipBooleanFilter(
1160
1095
  field_name="tagged_vlans",
@@ -1165,7 +1100,6 @@ class InterfaceFilterSet(
1165
1100
  prefers_id=True,
1166
1101
  queryset=Interface.objects.all(),
1167
1102
  to_field_name="name",
1168
- label="Child interfaces (name or ID)",
1169
1103
  )
1170
1104
  has_child_interfaces = RelatedMembershipBooleanFilter(
1171
1105
  field_name="child_interfaces",
@@ -1176,7 +1110,6 @@ class InterfaceFilterSet(
1176
1110
  prefers_id=True,
1177
1111
  to_field_name="name",
1178
1112
  queryset=Interface.objects.all(),
1179
- label="Bridged interfaces (name or ID)",
1180
1113
  )
1181
1114
  has_bridged_interfaces = RelatedMembershipBooleanFilter(
1182
1115
  field_name="bridged_interfaces",
@@ -1187,7 +1120,6 @@ class InterfaceFilterSet(
1187
1120
  prefers_id=True,
1188
1121
  to_field_name="name",
1189
1122
  queryset=Interface.objects.all(),
1190
- label="Member interfaces (name or ID)",
1191
1123
  )
1192
1124
  has_member_interfaces = RelatedMembershipBooleanFilter(
1193
1125
  field_name="member_interfaces",
@@ -1210,7 +1142,6 @@ class InterfaceFilterSet(
1210
1142
  virtual_device_contexts = NaturalKeyOrPKMultipleChoiceFilter(
1211
1143
  queryset=VirtualDeviceContext.objects.all(),
1212
1144
  to_field_name="name",
1213
- label="Virtual Device Context (name or ID)",
1214
1145
  )
1215
1146
  has_virtual_device_contexts = RelatedMembershipBooleanFilter(
1216
1147
  field_name="virtual_device_contexts",
@@ -1309,7 +1240,6 @@ class FrontPortFilterSet(ModularDeviceComponentModelFilterSetMixin, CableTermina
1309
1240
  prefers_id=True,
1310
1241
  to_field_name="name",
1311
1242
  queryset=RearPort.objects.all(),
1312
- label="Rear port (name or ID)",
1313
1243
  )
1314
1244
 
1315
1245
  class Meta:
@@ -1321,7 +1251,6 @@ class RearPortFilterSet(ModularDeviceComponentModelFilterSetMixin, CableTerminat
1321
1251
  front_ports = NaturalKeyOrPKMultipleChoiceFilter(
1322
1252
  to_field_name="name",
1323
1253
  queryset=FrontPort.objects.all(),
1324
- label="Front ports (name or ID)",
1325
1254
  )
1326
1255
  has_front_ports = RelatedMembershipBooleanFilter(
1327
1256
  field_name="front_ports",
@@ -1340,7 +1269,6 @@ class DeviceBayFilterSet(DeviceComponentModelFilterSetMixin, BaseFilterSet):
1340
1269
  field_name="installed_device",
1341
1270
  to_field_name="name",
1342
1271
  queryset=Device.objects.all(),
1343
- label="Installed device (name or ID)",
1344
1272
  )
1345
1273
 
1346
1274
  class Meta:
@@ -1368,14 +1296,12 @@ class InventoryItemFilterSet(DeviceComponentModelFilterSetMixin, BaseFilterSet):
1368
1296
  queryset=Location.objects.all(),
1369
1297
  field_name="device__location",
1370
1298
  to_field_name="name",
1371
- label="Location (name or ID)",
1372
1299
  )
1373
1300
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
1374
1301
  device = NaturalKeyOrPKMultipleChoiceFilter(
1375
1302
  prefers_id=True,
1376
1303
  queryset=Device.objects.all(),
1377
1304
  to_field_name="name",
1378
- label="Device (name or ID)",
1379
1305
  )
1380
1306
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
1381
1307
  parent = NaturalKeyOrPKMultipleChoiceFilter(
@@ -1387,7 +1313,6 @@ class InventoryItemFilterSet(DeviceComponentModelFilterSetMixin, BaseFilterSet):
1387
1313
  manufacturer = NaturalKeyOrPKMultipleChoiceFilter(
1388
1314
  queryset=Manufacturer.objects.all(),
1389
1315
  to_field_name="name",
1390
- label="Manufacturer (name or ID)",
1391
1316
  )
1392
1317
  # TODO: solve https://github.com/nautobot/nautobot/issues/2875 to use this filter correctly
1393
1318
  children = NaturalKeyOrPKMultipleChoiceFilter(
@@ -1408,7 +1333,6 @@ class InventoryItemFilterSet(DeviceComponentModelFilterSetMixin, BaseFilterSet):
1408
1333
  software_image_files = NaturalKeyOrPKMultipleChoiceFilter(
1409
1334
  queryset=SoftwareImageFile.objects.all(),
1410
1335
  to_field_name="image_file_name",
1411
- label="Software image files (image file name or ID)",
1412
1336
  )
1413
1337
  has_software_version = RelatedMembershipBooleanFilter(
1414
1338
  field_name="software_version",
@@ -1417,7 +1341,6 @@ class InventoryItemFilterSet(DeviceComponentModelFilterSetMixin, BaseFilterSet):
1417
1341
  software_version = NaturalKeyOrPKMultipleChoiceFilter(
1418
1342
  queryset=SoftwareVersion.objects.all(),
1419
1343
  to_field_name="version",
1420
- label="Software version (version or ID)",
1421
1344
  )
1422
1345
 
1423
1346
  class Meta:
@@ -1451,7 +1374,6 @@ class VirtualChassisFilterSet(NautobotFilterSet):
1451
1374
  prefers_id=True,
1452
1375
  queryset=Device.objects.all(),
1453
1376
  to_field_name="name",
1454
- label="Master (name or ID)",
1455
1377
  )
1456
1378
  # TODO Check this filter as it is not using TreeNode...
1457
1379
  location = NaturalKeyOrPKMultipleChoiceFilter(
@@ -1575,12 +1497,6 @@ class ConnectionFilterSetMixin:
1575
1497
  return queryset.filter(**{f"{name}__in": value})
1576
1498
 
1577
1499
 
1578
- # TODO: remove in 2.2
1579
- @class_deprecated_in_favor_of(ConnectionFilterSetMixin)
1580
- class ConnectionFilterSet(ConnectionFilterSetMixin):
1581
- pass
1582
-
1583
-
1584
1500
  class ConsoleConnectionFilterSet(ConnectionFilterSetMixin, BaseFilterSet):
1585
1501
  location = django_filters.CharFilter(
1586
1502
  method="filter_location",
@@ -1633,7 +1549,6 @@ class PowerPanelFilterSet(LocatableModelFilterSetMixin, NautobotFilterSet):
1633
1549
  prefers_id=True,
1634
1550
  to_field_name="name",
1635
1551
  queryset=PowerFeed.objects.all(),
1636
- label="Power feeds (name or ID)",
1637
1552
  )
1638
1553
  has_power_feeds = RelatedMembershipBooleanFilter(
1639
1554
  field_name="power_feeds",
@@ -1668,7 +1583,6 @@ class PowerFeedFilterSet(
1668
1583
  prefers_id=True,
1669
1584
  queryset=PowerPanel.objects.all(),
1670
1585
  to_field_name="name",
1671
- label="Power panel (name or ID)",
1672
1586
  )
1673
1587
  destination_panel = NaturalKeyOrPKMultipleChoiceFilter(
1674
1588
  prefers_id=True,
@@ -1681,7 +1595,6 @@ class PowerFeedFilterSet(
1681
1595
  prefers_id=True,
1682
1596
  queryset=Rack.objects.all(),
1683
1597
  to_field_name="name",
1684
- label="Rack (name or ID)",
1685
1598
  )
1686
1599
 
1687
1600
  class Meta:
@@ -1710,7 +1623,6 @@ class DeviceRedundancyGroupFilterSet(NautobotFilterSet, StatusModelFilterSetMixi
1710
1623
  secrets_group = NaturalKeyOrPKMultipleChoiceFilter(
1711
1624
  queryset=SecretsGroup.objects.all(),
1712
1625
  to_field_name="name",
1713
- label="Secrets group (name or ID)",
1714
1626
  )
1715
1627
 
1716
1628
  class Meta:
@@ -1726,7 +1638,6 @@ class InterfaceRedundancyGroupFilterSet(NameSearchFilterSet, BaseFilterSet):
1726
1638
  field_name="secrets_group",
1727
1639
  queryset=SecretsGroup.objects.all(),
1728
1640
  to_field_name="name",
1729
- label="Secrets group",
1730
1641
  )
1731
1642
  virtual_ip = MultiValueCharFilter(
1732
1643
  method="filter_virtual_ip",
@@ -1758,13 +1669,11 @@ class InterfaceRedundancyGroupAssociationFilterSet(BaseFilterSet):
1758
1669
  interface_redundancy_group = NaturalKeyOrPKMultipleChoiceFilter(
1759
1670
  queryset=InterfaceRedundancyGroup.objects.all(),
1760
1671
  to_field_name="name",
1761
- label="Interface Redundancy Groups (name or ID)",
1762
1672
  )
1763
1673
 
1764
1674
  interface = NaturalKeyOrPKMultipleChoiceFilter(
1765
1675
  queryset=Interface.objects.all(),
1766
1676
  to_field_name="name",
1767
- label="Interface (name or ID)",
1768
1677
  )
1769
1678
 
1770
1679
  class Meta:
@@ -1789,12 +1698,10 @@ class SoftwareImageFileFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1789
1698
  software_version = NaturalKeyOrPKMultipleChoiceFilter(
1790
1699
  queryset=SoftwareVersion.objects.all(),
1791
1700
  to_field_name="version",
1792
- label="Software version (version or ID)",
1793
1701
  )
1794
1702
  device_types = NaturalKeyOrPKMultipleChoiceFilter(
1795
1703
  queryset=DeviceType.objects.all(),
1796
1704
  to_field_name="model",
1797
- label="Device types (model or ID)",
1798
1705
  )
1799
1706
  has_device_types = RelatedMembershipBooleanFilter(
1800
1707
  field_name="device_types",
@@ -1802,7 +1709,6 @@ class SoftwareImageFileFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1802
1709
  )
1803
1710
  devices = NaturalKeyOrPKMultipleChoiceFilter(
1804
1711
  queryset=Device.objects.all(),
1805
- label="Devices (name or ID)",
1806
1712
  )
1807
1713
  has_devices = RelatedMembershipBooleanFilter(
1808
1714
  field_name="devices",
@@ -1814,7 +1720,6 @@ class SoftwareImageFileFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1814
1720
  external_integration = NaturalKeyOrPKMultipleChoiceFilter(
1815
1721
  queryset=ExternalIntegration.objects.all(),
1816
1722
  to_field_name="name",
1817
- label="External integration (name or ID)",
1818
1723
  )
1819
1724
 
1820
1725
  class Meta:
@@ -1834,7 +1739,6 @@ class SoftwareVersionFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1834
1739
  )
1835
1740
  devices = NaturalKeyOrPKMultipleChoiceFilter(
1836
1741
  queryset=Device.objects.all(),
1837
- label="Devices (name or ID)",
1838
1742
  )
1839
1743
  has_devices = RelatedMembershipBooleanFilter(
1840
1744
  field_name="devices",
@@ -1842,7 +1746,6 @@ class SoftwareVersionFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1842
1746
  )
1843
1747
  inventory_items = NaturalKeyOrPKMultipleChoiceFilter(
1844
1748
  queryset=InventoryItem.objects.all(),
1845
- label="Inventory items (name or ID)",
1846
1749
  )
1847
1750
  has_inventory_items = RelatedMembershipBooleanFilter(
1848
1751
  field_name="inventory_items",
@@ -1850,7 +1753,6 @@ class SoftwareVersionFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1850
1753
  )
1851
1754
  virtual_machines = NaturalKeyOrPKMultipleChoiceFilter(
1852
1755
  queryset=VirtualMachine.objects.all(),
1853
- label="Virtual machines (name or ID)",
1854
1756
  )
1855
1757
  has_virtual_machines = RelatedMembershipBooleanFilter(
1856
1758
  field_name="virtual_machines",
@@ -1859,7 +1761,6 @@ class SoftwareVersionFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1859
1761
  platform = NaturalKeyOrPKMultipleChoiceFilter(
1860
1762
  queryset=Platform.objects.all(),
1861
1763
  to_field_name="name",
1862
- label="Platform (name or ID)",
1863
1764
  )
1864
1765
  device_types = NaturalKeyOrPKMultipleChoiceFilter(
1865
1766
  field_name="software_image_files__device_types",
@@ -1874,7 +1775,6 @@ class SoftwareVersionFilterSet(NautobotFilterSet, StatusModelFilterSetMixin):
1874
1775
  software_image_files = NaturalKeyOrPKMultipleChoiceFilter(
1875
1776
  queryset=SoftwareImageFile.objects.all(),
1876
1777
  to_field_name="image_file_name",
1877
- label="Software image files (image file name or ID)",
1878
1778
  )
1879
1779
 
1880
1780
  class Meta:
@@ -1895,12 +1795,10 @@ class DeviceTypeToSoftwareImageFileFilterSet(BaseFilterSet):
1895
1795
  device_type = NaturalKeyOrPKMultipleChoiceFilter(
1896
1796
  queryset=DeviceType.objects.all(),
1897
1797
  to_field_name="model",
1898
- label="Device type (model or ID)",
1899
1798
  )
1900
1799
  software_image_file = NaturalKeyOrPKMultipleChoiceFilter(
1901
1800
  queryset=SoftwareImageFile.objects.all(),
1902
1801
  to_field_name="image_file_name",
1903
- label="Software image file (image file name or ID)",
1904
1802
  )
1905
1803
 
1906
1804
  class Meta:
@@ -1926,12 +1824,10 @@ class ControllerFilterSet(
1926
1824
  platform = NaturalKeyOrPKMultipleChoiceFilter(
1927
1825
  queryset=Platform.objects.all(),
1928
1826
  to_field_name="name",
1929
- label="Platform (name or ID)",
1930
1827
  )
1931
1828
  external_integration = NaturalKeyOrPKMultipleChoiceFilter(
1932
1829
  queryset=ExternalIntegration.objects.all(),
1933
1830
  to_field_name="name",
1934
- label="External integration (name or ID)",
1935
1831
  )
1936
1832
  capabilities = django_filters.MultipleChoiceFilter(
1937
1833
  choices=ControllerCapabilitiesChoices,
@@ -1942,12 +1838,10 @@ class ControllerFilterSet(
1942
1838
  controller_device = NaturalKeyOrPKMultipleChoiceFilter(
1943
1839
  queryset=Device.objects.all(),
1944
1840
  to_field_name="name",
1945
- label="Controller device (name or ID)",
1946
1841
  )
1947
1842
  controller_device_redundancy_group = NaturalKeyOrPKMultipleChoiceFilter(
1948
1843
  queryset=DeviceRedundancyGroup.objects.all(),
1949
1844
  to_field_name="name",
1950
- label="Controller device redundancy group (name or ID)",
1951
1845
  )
1952
1846
  wireless_networks = NaturalKeyOrPKMultipleChoiceFilter(
1953
1847
  field_name="controller_managed_device_groups__wireless_networks",
@@ -1981,7 +1875,6 @@ class ControllerManagedDeviceGroupFilterSet(
1981
1875
  controller = NaturalKeyOrPKMultipleChoiceFilter(
1982
1876
  queryset=Controller.objects.all(),
1983
1877
  to_field_name="name",
1984
- label="Controller (name or ID)",
1985
1878
  )
1986
1879
  parent = NaturalKeyOrPKMultipleChoiceFilter(
1987
1880
  queryset=ControllerManagedDeviceGroup.objects.all(),
@@ -1996,7 +1889,6 @@ class ControllerManagedDeviceGroupFilterSet(
1996
1889
  )
1997
1890
  radio_profiles = NaturalKeyOrPKMultipleChoiceFilter(
1998
1891
  queryset=RadioProfile.objects.all(),
1999
- label="Radio Profiles (name or ID)",
2000
1892
  )
2001
1893
  has_radio_profiles = RelatedMembershipBooleanFilter(
2002
1894
  field_name="radio_profiles",
@@ -2004,7 +1896,6 @@ class ControllerManagedDeviceGroupFilterSet(
2004
1896
  )
2005
1897
  wireless_networks = NaturalKeyOrPKMultipleChoiceFilter(
2006
1898
  queryset=WirelessNetwork.objects.all(),
2007
- label="Wireless Networks (name or ID)",
2008
1899
  )
2009
1900
  has_wireless_networks = RelatedMembershipBooleanFilter(
2010
1901
  field_name="wireless_networks",
@@ -2090,7 +1981,6 @@ class ModuleFilterSet(
2090
1981
  module_type = NaturalKeyOrPKMultipleChoiceFilter(
2091
1982
  queryset=ModuleType.objects.all(),
2092
1983
  to_field_name="model",
2093
- label="Module type (model or ID)",
2094
1984
  )
2095
1985
  module_family = NaturalKeyOrPKMultipleChoiceFilter(
2096
1986
  field_name="module_type__module_family",
@@ -2098,16 +1988,12 @@ class ModuleFilterSet(
2098
1988
  to_field_name="name",
2099
1989
  label="Module family (name or ID)",
2100
1990
  )
2101
- parent_module_bay = django_filters.ModelMultipleChoiceFilter(
2102
- queryset=ModuleBay.objects.all(),
2103
- label="Parent Module Bay",
2104
- )
2105
1991
  device = NaturalKeyOrPKMultipleChoiceFilter(
2106
1992
  queryset=Device.objects.all(),
2107
1993
  to_field_name="name",
2108
- label="Device (name or ID)",
2109
1994
  method="filter_device",
2110
1995
  )
1996
+ # TODO: change to a ModelMultipleChoiceFilter as a breaking change for Dynamic Group and permission definitions
2111
1997
  compatible_with_module_bay = extend_schema_field({"type": "string", "format": "uuid"})(
2112
1998
  django_filters.ModelChoiceFilter(
2113
1999
  queryset=ModuleBay.objects.all(),
@@ -2175,13 +2061,12 @@ class ModuleTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
2175
2061
  manufacturer = NaturalKeyOrPKMultipleChoiceFilter(
2176
2062
  queryset=Manufacturer.objects.all(),
2177
2063
  to_field_name="name",
2178
- label="Manufacturer (name or ID)",
2179
2064
  )
2180
2065
  module_family = NaturalKeyOrPKMultipleChoiceFilter(
2181
2066
  queryset=ModuleFamily.objects.all(),
2182
2067
  to_field_name="name",
2183
- label="Module family (name or ID)",
2184
2068
  )
2069
+ # TODO: change to a ModelMultipleChoiceFilter as a breaking change for Dynamic Group and permission definitions
2185
2070
  compatible_with_module_bay = extend_schema_field({"type": "string", "format": "uuid"})(
2186
2071
  django_filters.ModelChoiceFilter(
2187
2072
  queryset=ModuleBay.objects.all(),
@@ -2237,7 +2122,6 @@ class ModuleBayTemplateFilterSet(ModularDeviceComponentTemplateModelFilterSetMix
2237
2122
  module_family = NaturalKeyOrPKMultipleChoiceFilter(
2238
2123
  queryset=ModuleFamily.objects.all(),
2239
2124
  to_field_name="name",
2240
- label="Module family (name or ID)",
2241
2125
  )
2242
2126
  requires_first_party_modules = django_filters.BooleanFilter(
2243
2127
  label="Requires first-party modules",
@@ -2276,23 +2160,18 @@ class ModuleBayFilterSet(NautobotFilterSet):
2276
2160
  parent_device = NaturalKeyOrPKMultipleChoiceFilter(
2277
2161
  queryset=Device.objects.all(),
2278
2162
  to_field_name="name",
2279
- label="Parent device (name or ID)",
2280
2163
  )
2281
2164
  has_parent_device = RelatedMembershipBooleanFilter(
2282
2165
  field_name="parent_device",
2283
2166
  label="Has parent device",
2284
2167
  )
2285
- parent_module = django_filters.ModelMultipleChoiceFilter(
2286
- queryset=Module.objects.all(),
2287
- label="Parent module (ID)",
2288
- )
2289
2168
  has_parent_module = RelatedMembershipBooleanFilter(
2290
2169
  field_name="parent_module",
2291
2170
  label="Has parent module",
2292
2171
  )
2293
- installed_module = django_filters.ModelMultipleChoiceFilter(
2172
+ # needed because this is a *reverse* OneToOneField and so doesn't get included automatically in "__all__"
2173
+ installed_module = ModelMultipleChoiceFilter(
2294
2174
  queryset=Module.objects.all(),
2295
- label="Installed module (ID)",
2296
2175
  )
2297
2176
  has_installed_module = RelatedMembershipBooleanFilter(
2298
2177
  field_name="installed_module",
@@ -2301,7 +2180,6 @@ class ModuleBayFilterSet(NautobotFilterSet):
2301
2180
  module_family = NaturalKeyOrPKMultipleChoiceFilter(
2302
2181
  queryset=ModuleFamily.objects.all(),
2303
2182
  to_field_name="name",
2304
- label="Module family (name or ID)",
2305
2183
  )
2306
2184
  requires_first_party_modules = django_filters.BooleanFilter(
2307
2185
  field_name="requires_first_party_modules",
@@ -2347,13 +2225,11 @@ class VirtualDeviceContextFilterSet(
2347
2225
  device = NaturalKeyOrPKMultipleChoiceFilter(
2348
2226
  queryset=Device.objects.all(),
2349
2227
  to_field_name="name",
2350
- label="Device (name or ID)",
2351
2228
  )
2352
2229
  interfaces = NaturalKeyOrPKMultipleChoiceFilter(
2353
2230
  prefers_id=True,
2354
2231
  queryset=Interface.objects.all(),
2355
2232
  to_field_name="name",
2356
- label="Interface (name or ID)",
2357
2233
  )
2358
2234
  has_interfaces = RelatedMembershipBooleanFilter(
2359
2235
  field_name="interfaces",
@@ -2425,13 +2301,11 @@ class InterfaceVDCAssignmentFilterSet(NautobotFilterSet):
2425
2301
  virtual_device_context = NaturalKeyOrPKMultipleChoiceFilter(
2426
2302
  queryset=VirtualDeviceContext.objects.all(),
2427
2303
  to_field_name="name",
2428
- label="Virtual Device Context (name or ID)",
2429
2304
  )
2430
2305
  interface = NaturalKeyOrPKMultipleChoiceFilter(
2431
2306
  prefers_id=True,
2432
2307
  queryset=Interface.objects.all(),
2433
2308
  to_field_name="name",
2434
- label="Interface (name or ID)",
2435
2309
  )
2436
2310
 
2437
2311
  class Meta:
@@ -2470,11 +2344,10 @@ class ModuleFamilyFilterSet(NautobotFilterSet):
2470
2344
  module_types = NaturalKeyOrPKMultipleChoiceFilter(
2471
2345
  queryset=ModuleType.objects.all(),
2472
2346
  to_field_name="model",
2473
- label="Module types (model or ID)",
2474
2347
  )
2475
2348
 
2476
2349
  module_bay_id = extend_schema_field({"type": "array", "items": {"type": "string", "format": "uuid"}})(
2477
- django_filters.ModelMultipleChoiceFilter(
2350
+ ModelMultipleChoiceFilter(
2478
2351
  queryset=ModuleBay.objects.all(),
2479
2352
  label="Module bay (ID)",
2480
2353
  )
@@ -2490,3 +2363,43 @@ class ModuleFamilyFilterSet(NautobotFilterSet):
2490
2363
  "module_bay_id",
2491
2364
  "tags",
2492
2365
  ]
2366
+
2367
+
2368
+ class DeviceClusterAssignmentFilterSet(NautobotFilterSet):
2369
+ """Filters for DeviceClusterAssignment model."""
2370
+
2371
+ q = SearchFilter(
2372
+ filter_predicates={
2373
+ "device__name": {
2374
+ "lookup_expr": "icontains",
2375
+ "preprocessor": str.strip,
2376
+ },
2377
+ "device__asset_tag": {
2378
+ "lookup_expr": "icontains",
2379
+ "preprocessor": str.strip,
2380
+ },
2381
+ "device__serial": {
2382
+ "lookup_expr": "icontains",
2383
+ "preprocessor": str.strip,
2384
+ },
2385
+ "cluster__name": {
2386
+ "lookup_expr": "icontains",
2387
+ "preprocessor": str.strip,
2388
+ },
2389
+ }
2390
+ )
2391
+
2392
+ device = NaturalKeyOrPKMultipleChoiceFilter(
2393
+ queryset=Device.objects.all(),
2394
+ to_field_name="name",
2395
+ label="Device (name or ID)",
2396
+ )
2397
+ cluster = NaturalKeyOrPKMultipleChoiceFilter(
2398
+ queryset=Cluster.objects.all(),
2399
+ to_field_name="name",
2400
+ label="Cluster (name or ID)",
2401
+ )
2402
+
2403
+ class Meta:
2404
+ model = DeviceClusterAssignment
2405
+ fields = ["device", "cluster"]