nautobot 2.0.0a2__py3-none-any.whl → 2.0.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1029) hide show
  1. nautobot/__init__.py +1 -5
  2. nautobot/apps/api.py +6 -8
  3. nautobot/apps/forms.py +0 -2
  4. nautobot/apps/ui.py +0 -8
  5. nautobot/circuits/api/serializers.py +9 -119
  6. nautobot/circuits/api/urls.py +1 -1
  7. nautobot/circuits/api/views.py +0 -1
  8. nautobot/circuits/choices.py +0 -2
  9. nautobot/circuits/filters.py +7 -6
  10. nautobot/circuits/forms.py +3 -73
  11. nautobot/circuits/migrations/0001_initial_part_1.py +0 -1
  12. nautobot/circuits/migrations/0002_initial_part_2.py +0 -1
  13. nautobot/circuits/migrations/0003_auto_slug.py +0 -1
  14. nautobot/circuits/migrations/0004_increase_provider_account_length.py +0 -1
  15. nautobot/circuits/migrations/0005_providernetwork.py +0 -1
  16. nautobot/circuits/migrations/0006_cache_circuit_terminations.py +0 -1
  17. nautobot/circuits/migrations/0007_circuitterminations_primary_model.py +0 -1
  18. nautobot/circuits/migrations/0008_add_natural_indexing.py +0 -1
  19. nautobot/circuits/migrations/0009_circuittermination_location.py +0 -1
  20. nautobot/circuits/migrations/0010_rename_foreign_keys_and_related_names.py +0 -1
  21. nautobot/circuits/migrations/0011_remove_site_foreign_key_from_circuit_termination_class.py +0 -1
  22. nautobot/circuits/migrations/0012_created_datetime.py +0 -1
  23. nautobot/circuits/migrations/0013_alter_circuittermination__path.py +0 -1
  24. nautobot/circuits/migrations/0014_related_name_changes.py +1 -2
  25. nautobot/circuits/migrations/0015_remove_circuittype_provider_slug.py +20 -0
  26. nautobot/circuits/migrations/0016_tagsfield.py +34 -0
  27. nautobot/circuits/migrations/0017_fixup_null_statuses.py +22 -0
  28. nautobot/circuits/migrations/0018_status_nonnullable.py +22 -0
  29. nautobot/circuits/models.py +3 -93
  30. nautobot/circuits/navigation.py +14 -69
  31. nautobot/circuits/signals.py +0 -2
  32. nautobot/circuits/tables.py +42 -5
  33. nautobot/circuits/templates/circuits/circuit_retrieve.html +1 -1
  34. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +1 -1
  35. nautobot/circuits/templates/circuits/circuittype_retrieve.html +1 -1
  36. nautobot/circuits/templates/circuits/provider_create.html +0 -1
  37. nautobot/circuits/templates/circuits/provider_retrieve.html +1 -1
  38. nautobot/circuits/tests/integration/test_relationships.py +13 -16
  39. nautobot/circuits/tests/test_api.py +13 -43
  40. nautobot/circuits/tests/test_filters.py +20 -15
  41. nautobot/circuits/tests/test_models.py +7 -3
  42. nautobot/circuits/tests/test_views.py +57 -67
  43. nautobot/circuits/views.py +18 -9
  44. nautobot/core/api/__init__.py +8 -2
  45. nautobot/core/api/authentication.py +0 -3
  46. nautobot/core/api/fields.py +15 -6
  47. nautobot/core/api/filter_backends.py +3 -2
  48. nautobot/core/api/metadata.py +237 -30
  49. nautobot/core/api/mixins.py +94 -0
  50. nautobot/core/api/pagination.py +3 -3
  51. nautobot/core/api/parsers.py +154 -0
  52. nautobot/core/api/renderers.py +153 -2
  53. nautobot/core/api/schema.py +47 -3
  54. nautobot/core/api/serializers.py +377 -37
  55. nautobot/core/api/urls.py +11 -3
  56. nautobot/core/api/utils.py +174 -2
  57. nautobot/core/api/versioning.py +32 -10
  58. nautobot/core/api/views.py +266 -75
  59. nautobot/core/apps/__init__.py +138 -221
  60. nautobot/core/celery/__init__.py +112 -41
  61. nautobot/core/celery/backends.py +19 -13
  62. nautobot/core/celery/control.py +46 -0
  63. nautobot/core/celery/encoders.py +53 -0
  64. nautobot/core/celery/log.py +38 -0
  65. nautobot/core/celery/schedulers.py +23 -4
  66. nautobot/core/celery/task.py +1 -16
  67. nautobot/core/checks.py +0 -27
  68. nautobot/core/choices.py +21 -113
  69. nautobot/core/{cli.py → cli/__init__.py} +1 -2
  70. nautobot/core/cli/__main__.py +3 -0
  71. nautobot/core/constants.py +25 -43
  72. nautobot/core/context_processors.py +12 -0
  73. nautobot/core/filters.py +2 -2
  74. nautobot/core/forms/__init__.py +0 -4
  75. nautobot/core/forms/fields.py +39 -68
  76. nautobot/core/forms/forms.py +27 -27
  77. nautobot/core/forms/utils.py +7 -59
  78. nautobot/core/forms/widgets.py +0 -1
  79. nautobot/core/graphql/__init__.py +2 -2
  80. nautobot/core/graphql/schema.py +4 -27
  81. nautobot/core/jobs/__init__.py +75 -0
  82. nautobot/core/management/commands/build_ui.py +255 -0
  83. nautobot/core/management/commands/celery.py +0 -1
  84. nautobot/core/management/commands/generate_test_data.py +18 -13
  85. nautobot/core/management/commands/post_upgrade.py +24 -24
  86. nautobot/core/management/commands/validate_models.py +0 -1
  87. nautobot/core/middleware.py +0 -1
  88. nautobot/core/models/__init__.py +26 -1
  89. nautobot/core/models/fields.py +24 -5
  90. nautobot/core/models/generics.py +2 -46
  91. nautobot/core/models/managers.py +5 -0
  92. nautobot/core/models/name_color_content_types.py +1 -19
  93. nautobot/core/models/tree_queries.py +14 -4
  94. nautobot/core/models/utils.py +9 -10
  95. nautobot/core/models/validators.py +17 -8
  96. nautobot/core/releases.py +8 -10
  97. nautobot/core/settings.py +81 -53
  98. nautobot/core/tables.py +5 -5
  99. nautobot/core/tasks.py +4 -7
  100. nautobot/core/templates/base.html +1 -49
  101. nautobot/core/templates/base_django.html +49 -0
  102. nautobot/core/templates/base_react.html +55 -0
  103. nautobot/core/templates/buttons/export.html +6 -4
  104. nautobot/core/templates/generic/object_bulk_create.html +10 -21
  105. nautobot/core/templates/generic/object_list.html +4 -1
  106. nautobot/core/templates/generic/object_retrieve_plugin_full_width.html +3 -0
  107. nautobot/core/templates/inc/footer.html +1 -0
  108. nautobot/core/templates/inc/javascript.html +0 -14
  109. nautobot/core/templates/inc/nav_menu.html +28 -33
  110. nautobot/core/templates/inc/object_details_advanced_panel.html +13 -0
  111. nautobot/core/templates/inc/relationships_table_rows.html +2 -2
  112. nautobot/core/templates/nautobot_config.py.j2 +8 -25
  113. nautobot/core/templates/plugin_template/__init__.py-tpl +1 -2
  114. nautobot/core/templates/rest_framework/api.html +8 -0
  115. nautobot/core/templatetags/buttons.py +32 -29
  116. nautobot/core/templatetags/helpers.py +1 -1
  117. nautobot/core/testing/__init__.py +47 -44
  118. nautobot/core/testing/api.py +365 -47
  119. nautobot/core/testing/filters.py +12 -7
  120. nautobot/core/testing/integration.py +1 -1
  121. nautobot/core/testing/migrations.py +2 -0
  122. nautobot/core/testing/mixins.py +22 -12
  123. nautobot/core/testing/schema.py +2 -1
  124. nautobot/core/testing/views.py +28 -51
  125. nautobot/core/tests/integration/test_filters.py +17 -8
  126. nautobot/core/tests/integration/test_navbar.py +11 -34
  127. nautobot/core/tests/integration/test_plugin_navbar.py +9 -103
  128. nautobot/core/tests/nautobot_config.py +2 -3
  129. nautobot/core/tests/runner.py +0 -1
  130. nautobot/core/tests/test_api.py +290 -24
  131. nautobot/core/tests/test_authentication.py +57 -14
  132. nautobot/core/tests/test_checks.py +0 -7
  133. nautobot/core/tests/test_choices.py +0 -1
  134. nautobot/core/tests/test_filters.py +117 -110
  135. nautobot/core/tests/test_forms.py +47 -110
  136. nautobot/core/tests/test_graphql.py +158 -135
  137. nautobot/core/tests/test_logging.py +4 -1
  138. nautobot/core/tests/test_managers.py +3 -5
  139. nautobot/core/tests/test_models.py +2 -0
  140. nautobot/core/tests/test_ordering.py +0 -2
  141. nautobot/core/tests/test_paginator.py +3 -1
  142. nautobot/core/tests/test_releases.py +12 -12
  143. nautobot/core/tests/test_templatetags_helpers.py +7 -4
  144. nautobot/core/tests/test_utils.py +112 -78
  145. nautobot/core/tests/test_views.py +12 -17
  146. nautobot/core/tests/test_views_utils.py +6 -9
  147. nautobot/core/utils/data.py +17 -0
  148. nautobot/core/utils/deprecation.py +13 -20
  149. nautobot/core/utils/filtering.py +53 -9
  150. nautobot/core/utils/git.py +12 -4
  151. nautobot/core/utils/lookup.py +3 -1
  152. nautobot/core/utils/requests.py +23 -116
  153. nautobot/core/views/__init__.py +1 -2
  154. nautobot/core/views/generic.py +131 -119
  155. nautobot/core/views/mixins.py +53 -62
  156. nautobot/core/views/paginator.py +0 -1
  157. nautobot/core/views/renderers.py +14 -12
  158. nautobot/core/views/utils.py +87 -4
  159. nautobot/dcim/api/serializers.py +160 -672
  160. nautobot/dcim/api/urls.py +1 -1
  161. nautobot/dcim/api/views.py +7 -46
  162. nautobot/dcim/choices.py +2 -25
  163. nautobot/dcim/elevations.py +0 -1
  164. nautobot/dcim/factory.py +15 -4
  165. nautobot/dcim/filters/__init__.py +42 -13
  166. nautobot/dcim/form_mixins.py +1 -27
  167. nautobot/dcim/forms.py +58 -797
  168. nautobot/dcim/management/commands/trace_paths.py +0 -1
  169. nautobot/dcim/migrations/0001_initial_part_1.py +0 -1
  170. nautobot/dcim/migrations/0002_initial_part_2.py +0 -1
  171. nautobot/dcim/migrations/0003_initial_part_3.py +0 -1
  172. nautobot/dcim/migrations/0004_initial_part_4.py +0 -1
  173. nautobot/dcim/migrations/0005_device_local_context_schema.py +0 -1
  174. nautobot/dcim/migrations/0006_auto_slug.py +0 -1
  175. nautobot/dcim/migrations/0007_device_secrets_group.py +0 -1
  176. nautobot/dcim/migrations/0008_increase_all_serial_lengths.py +0 -1
  177. nautobot/dcim/migrations/0009_add_natural_indexing.py +0 -1
  178. nautobot/dcim/migrations/0010_interface_status.py +0 -1
  179. nautobot/dcim/migrations/0011_interface_status_data_migration.py +0 -1
  180. nautobot/dcim/migrations/0012_interface_parent_bridge.py +0 -1
  181. nautobot/dcim/migrations/0013_location_location_type.py +0 -1
  182. nautobot/dcim/migrations/0014_location_status_data_migration.py +0 -1
  183. nautobot/dcim/migrations/0015_device_components__changeloggedmodel.py +0 -1
  184. nautobot/dcim/migrations/0016_device_components__timestamp_data_migration.py +0 -1
  185. nautobot/dcim/migrations/0017_locationtype_nestable.py +0 -1
  186. nautobot/dcim/migrations/0018_device_redundancy_group.py +0 -1
  187. nautobot/dcim/migrations/0019_device_redundancy_group_data_migration.py +0 -1
  188. nautobot/dcim/migrations/0020_move_site_fields_to_location_model.py +0 -1
  189. nautobot/dcim/migrations/0021_mptt_to_tree_queries.py +0 -1
  190. nautobot/dcim/migrations/0022_interface_mac_address_data_migration.py +0 -1
  191. nautobot/dcim/migrations/0023_alter_interface_mac_address.py +0 -1
  192. nautobot/dcim/migrations/0024_alter_device_and_rack_role_add_new_role.py +2 -2
  193. nautobot/dcim/migrations/0025_device_and_rack_roles_data_migrations.py +19 -14
  194. nautobot/dcim/migrations/0026_rename_device_and_rack_role.py +0 -1
  195. nautobot/dcim/migrations/0027_remove_device_role_and_rack_role.py +1 -2
  196. nautobot/dcim/migrations/0028_rename_foreignkey_fields.py +1 -2
  197. nautobot/dcim/migrations/0029_add_tree_managers_and_foreign_keys_pre_data_migration.py +0 -1
  198. nautobot/dcim/migrations/0030_migrate_region_and_site_data_to_locations.py +2 -2
  199. nautobot/dcim/migrations/0031_rename_path_end_point_related_name.py +0 -1
  200. nautobot/dcim/migrations/0032_remove_site_foreign_key_from_dcim_models.py +0 -1
  201. nautobot/dcim/migrations/0033_created_datetime.py +0 -1
  202. nautobot/dcim/migrations/0034_fixup_fks_and_related_names.py +0 -1
  203. nautobot/dcim/migrations/0035_related_name_changes.py +1 -2
  204. nautobot/dcim/migrations/0036_remove_region_and_site.py +1 -2
  205. nautobot/dcim/migrations/0037_interface_ip_addresses_m2m.py +0 -1
  206. nautobot/dcim/migrations/0038_alter_location_managers.py +0 -1
  207. nautobot/dcim/migrations/0039_remove_slug.py +24 -0
  208. nautobot/dcim/migrations/0040_tagsfield.py +109 -0
  209. nautobot/dcim/migrations/0041_ipam__namespaces.py +25 -0
  210. nautobot/dcim/migrations/0042_fixup_null_statuses.py +51 -0
  211. nautobot/dcim/migrations/0043_status_nonnullable.py +72 -0
  212. nautobot/dcim/models/cables.py +4 -35
  213. nautobot/dcim/models/device_component_templates.py +7 -2
  214. nautobot/dcim/models/device_components.py +26 -203
  215. nautobot/dcim/models/devices.py +30 -152
  216. nautobot/dcim/models/locations.py +3 -64
  217. nautobot/dcim/models/power.py +3 -51
  218. nautobot/dcim/models/racks.py +7 -86
  219. nautobot/dcim/navigation.py +141 -467
  220. nautobot/dcim/signals.py +0 -2
  221. nautobot/dcim/tables/devices.py +8 -5
  222. nautobot/dcim/tables/devicetypes.py +1 -1
  223. nautobot/dcim/tables/locations.py +2 -2
  224. nautobot/dcim/tables/power.py +2 -2
  225. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -0
  226. nautobot/dcim/templates/dcim/device.html +15 -4
  227. nautobot/dcim/templates/dcim/device_edit.html +6 -0
  228. nautobot/dcim/templates/dcim/deviceredundancygroup_create.html +0 -1
  229. nautobot/dcim/templates/dcim/devicetype.html +2 -2
  230. nautobot/dcim/templates/dcim/interface.html +4 -0
  231. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -0
  232. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  233. nautobot/dcim/templates/dcim/location.html +16 -1
  234. nautobot/dcim/templates/dcim/locationtype.html +15 -0
  235. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -0
  236. nautobot/dcim/templates/dcim/rackgroup.html +0 -12
  237. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  238. nautobot/dcim/tests/test_api.py +202 -130
  239. nautobot/dcim/tests/test_cablepaths.py +47 -42
  240. nautobot/dcim/tests/test_filters.py +156 -134
  241. nautobot/dcim/tests/test_forms.py +12 -213
  242. nautobot/dcim/tests/test_graphql.py +8 -3
  243. nautobot/dcim/tests/test_migrations.py +6 -11
  244. nautobot/dcim/tests/test_models.py +208 -158
  245. nautobot/dcim/tests/test_natural_ordering.py +12 -14
  246. nautobot/dcim/tests/test_signals.py +7 -4
  247. nautobot/dcim/tests/test_views.py +270 -264
  248. nautobot/dcim/urls.py +21 -26
  249. nautobot/dcim/views.py +14 -156
  250. nautobot/docs/additional-features/caching.md +6 -87
  251. nautobot/docs/additional-features/job-scheduling-and-approvals.md +3 -0
  252. nautobot/docs/additional-features/jobs.md +179 -197
  253. nautobot/docs/administration/nautobot-server.md +9 -24
  254. nautobot/docs/administration/nautobot-shell.md +6 -6
  255. nautobot/docs/administration/replicating-nautobot.md +0 -10
  256. nautobot/docs/configuration/index.md +9 -9
  257. nautobot/docs/configuration/optional-settings.md +32 -61
  258. nautobot/docs/configuration/required-settings.md +11 -52
  259. nautobot/docs/development/application-registry.md +2 -13
  260. nautobot/docs/development/best-practices.md +2 -1
  261. nautobot/docs/development/docker-compose-advanced-use-cases.md +1 -1
  262. nautobot/docs/development/extending-models.md +15 -17
  263. nautobot/docs/development/generic-views.md +0 -2
  264. nautobot/docs/development/getting-started.md +56 -6
  265. nautobot/docs/development/navigation-menu.md +22 -93
  266. nautobot/docs/development/react-ui.md +105 -0
  267. nautobot/docs/development/release-checklist.md +3 -3
  268. nautobot/docs/development/role-internals.md +1 -3
  269. nautobot/docs/development/style-guide.md +6 -4
  270. nautobot/docs/development/templates.md +2 -1
  271. nautobot/docs/docker/index.md +16 -14
  272. nautobot/docs/index.md +7 -3
  273. nautobot/docs/installation/index.md +4 -1
  274. nautobot/docs/installation/migrating-from-netbox.md +12 -43
  275. nautobot/docs/installation/migrating-from-postgresql.md +1 -1
  276. nautobot/docs/installation/nautobot.md +1 -1
  277. nautobot/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
  278. nautobot/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
  279. nautobot/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
  280. nautobot/docs/installation/tables/v2-code-location-changes.yaml +241 -0
  281. nautobot/docs/installation/tables/v2-code-removals.yaml +67 -0
  282. nautobot/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
  283. nautobot/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
  284. nautobot/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
  285. nautobot/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
  286. nautobot/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
  287. nautobot/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
  288. nautobot/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
  289. nautobot/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
  290. nautobot/docs/installation/upgrading-from-nautobot-v1.md +190 -636
  291. nautobot/docs/installation/upgrading.md +5 -2
  292. nautobot/docs/models/dcim/device.md +3 -0
  293. nautobot/docs/models/dcim/deviceredundancygroup.md +3 -3
  294. nautobot/docs/models/extras/computedfield.md +4 -4
  295. nautobot/docs/models/extras/dynamicgroup.md +9 -9
  296. nautobot/docs/models/extras/gitrepository.md +3 -0
  297. nautobot/docs/models/extras/job.md +1 -0
  298. nautobot/docs/models/extras/jobbutton.md +18 -13
  299. nautobot/docs/models/extras/jobhook.md +7 -4
  300. nautobot/docs/models/extras/jobresult.md +6 -2
  301. nautobot/docs/models/extras/relationship.md +2 -2
  302. nautobot/docs/models/extras/status.md +6 -19
  303. nautobot/docs/models/ipam/ipaddress.md +3 -0
  304. nautobot/docs/models/ipam/vrf.md +0 -3
  305. nautobot/docs/models/virtualization/virtualmachine.md +3 -0
  306. nautobot/docs/plugins/development.md +92 -24
  307. nautobot/docs/release-notes/version-1.5.md +96 -0
  308. nautobot/docs/release-notes/version-2.0.md +216 -0
  309. nautobot/docs/requirements.txt +5 -4
  310. nautobot/docs/rest-api/overview.md +384 -215
  311. nautobot/docs/rest-api/ui-related-endpoints.md +9 -0
  312. nautobot/extras/admin.py +3 -5
  313. nautobot/extras/api/customfields.py +15 -39
  314. nautobot/extras/api/fields.py +0 -11
  315. nautobot/extras/api/mixins.py +45 -0
  316. nautobot/extras/api/relationships.py +63 -159
  317. nautobot/extras/api/serializers.py +165 -706
  318. nautobot/extras/api/urls.py +1 -1
  319. nautobot/extras/api/views.py +295 -282
  320. nautobot/extras/apps.py +4 -7
  321. nautobot/extras/choices.py +11 -22
  322. nautobot/extras/constants.py +9 -3
  323. nautobot/extras/datasources/__init__.py +2 -0
  324. nautobot/extras/datasources/git.py +135 -186
  325. nautobot/extras/datasources/registry.py +25 -35
  326. nautobot/extras/factory.py +1 -3
  327. nautobot/extras/filters/__init__.py +49 -47
  328. nautobot/extras/filters/mixins.py +10 -8
  329. nautobot/extras/forms/forms.py +72 -148
  330. nautobot/extras/forms/mixins.py +34 -57
  331. nautobot/extras/health_checks.py +0 -33
  332. nautobot/extras/jobs.py +387 -566
  333. nautobot/extras/management/__init__.py +55 -48
  334. nautobot/extras/management/commands/renaturalize.py +0 -1
  335. nautobot/extras/management/commands/runjob.py +24 -62
  336. nautobot/extras/management/commands/webhook_receiver.py +0 -1
  337. nautobot/extras/managers.py +30 -7
  338. nautobot/extras/migrations/0001_initial_part_1.py +0 -1
  339. nautobot/extras/migrations/0002_initial_part_2.py +0 -1
  340. nautobot/extras/migrations/0003_initial_part_3.py +0 -1
  341. nautobot/extras/migrations/0004_populate_default_status_records.py +0 -1
  342. nautobot/extras/migrations/0005_configcontext_device_types.py +0 -1
  343. nautobot/extras/migrations/0006_graphqlquery.py +0 -1
  344. nautobot/extras/migrations/0007_configcontextschema.py +0 -1
  345. nautobot/extras/migrations/0008_jobresult__custom_field_data.py +0 -1
  346. nautobot/extras/migrations/0009_computedfield.py +0 -1
  347. nautobot/extras/migrations/0010_change_cf_validation_max_min_field_to_bigint.py +0 -1
  348. nautobot/extras/migrations/0011_fileattachment_fileproxy.py +0 -1
  349. nautobot/extras/migrations/0012_healthchecktestmodel.py +0 -1
  350. nautobot/extras/migrations/0013_default_fallback_value_computedfield.py +0 -1
  351. nautobot/extras/migrations/0014_auto_slug.py +0 -1
  352. nautobot/extras/migrations/0015_scheduled_job.py +0 -1
  353. nautobot/extras/migrations/0016_secret.py +0 -1
  354. nautobot/extras/migrations/0017_joblogentry.py +0 -1
  355. nautobot/extras/migrations/0018_joblog_data_migration.py +0 -2
  356. nautobot/extras/migrations/0019_joblogentry__meta_options__related_name.py +0 -1
  357. nautobot/extras/migrations/0020_customfield_changelog.py +0 -1
  358. nautobot/extras/migrations/0021_customfield_changelog_data.py +0 -1
  359. nautobot/extras/migrations/0022_objectchange_object_datav2.py +0 -1
  360. nautobot/extras/migrations/0023_job_model.py +0 -1
  361. nautobot/extras/migrations/0024_job_data_migration.py +0 -1
  362. nautobot/extras/migrations/0025_add_advanced_ui_boolean_to_customfield_conputedfield_and_relationship.py +0 -1
  363. nautobot/extras/migrations/0026_job_add_gitrepository_fk.py +0 -1
  364. nautobot/extras/migrations/0027_job_gitrepository_data_migration.py +0 -1
  365. nautobot/extras/migrations/0028_job_reduce_source.py +0 -1
  366. nautobot/extras/migrations/0029_dynamicgroup.py +0 -1
  367. nautobot/extras/migrations/0030_webhook_alter_unique_together.py +0 -1
  368. nautobot/extras/migrations/0031_tag_content_types.py +0 -1
  369. nautobot/extras/migrations/0032_tag_content_types_data_migration.py +0 -1
  370. nautobot/extras/migrations/0033_add__optimized_indexing.py +0 -1
  371. nautobot/extras/migrations/0034_alter_fileattachment_mimetype.py +0 -1
  372. nautobot/extras/migrations/0035_scheduledjob_crontab.py +0 -1
  373. nautobot/extras/migrations/0036_job_add_has_sensitive_variables.py +0 -1
  374. nautobot/extras/migrations/0037_configcontextschema__remove_name_unique__create_constraint_unique_name_owner.py +0 -1
  375. nautobot/extras/migrations/0038_configcontext_locations.py +0 -1
  376. nautobot/extras/migrations/0039_objectchange__add_change_context.py +0 -1
  377. nautobot/extras/migrations/0040_dynamicgroup__dynamicgroupmembership.py +0 -1
  378. nautobot/extras/migrations/0041_jobresult_job_kwargs.py +0 -1
  379. nautobot/extras/migrations/0042_job__add_is_job_hook_receiver.py +0 -1
  380. nautobot/extras/migrations/0043_note.py +0 -1
  381. nautobot/extras/migrations/0044_add_job_hook.py +0 -1
  382. nautobot/extras/migrations/0045_add_custom_field_slug.py +0 -1
  383. nautobot/extras/migrations/0046_populate_custom_field_slug_label.py +0 -1
  384. nautobot/extras/migrations/0047_enforce_custom_field_slug.py +0 -1
  385. nautobot/extras/migrations/0048_alter_objectchange_change_context_detail.py +0 -1
  386. nautobot/extras/migrations/0049_alter_tag_slug.py +0 -1
  387. nautobot/extras/migrations/0050_customfield_grouping.py +0 -1
  388. nautobot/extras/migrations/0051_add_job_task_queues.py +0 -1
  389. nautobot/extras/migrations/0052_configcontext_device_redundancy_groups.py +0 -1
  390. nautobot/extras/migrations/0053_relationship_required_on.py +0 -1
  391. nautobot/extras/migrations/0054_scheduledjob_kwargs_request_user_change.py +0 -1
  392. nautobot/extras/migrations/0055_configcontext_dynamic_groups.py +0 -1
  393. nautobot/extras/migrations/0056_objectchange_add_reverse_time_idx.py +0 -1
  394. nautobot/extras/migrations/0057_jobbutton.py +0 -1
  395. nautobot/extras/migrations/0058_jobresult_add_time_status_idxs.py +38 -0
  396. nautobot/extras/migrations/{0058_joblogentry_scheduledjob_webhook_data_migration.py → 0059_joblogentry_scheduledjob_webhook_data_migration.py} +1 -2
  397. nautobot/extras/migrations/{0059_alter_joblogentry_scheduledjob_webhook_fields.py → 0060_alter_joblogentry_scheduledjob_webhook_fields.py} +1 -2
  398. nautobot/extras/migrations/{0060_role_and_alter_status.py → 0061_role_and_alter_status.py} +1 -8
  399. nautobot/extras/migrations/{0061_collect_roles_from_related_apps_roles.py → 0062_collect_roles_from_related_apps_roles.py} +33 -33
  400. nautobot/extras/migrations/{0062_alter_role_options.py → 0063_alter_role_options.py} +1 -2
  401. nautobot/extras/migrations/{0063_alter_configcontext_and_add_new_role.py → 0064_alter_configcontext_and_add_new_role.py} +1 -2
  402. nautobot/extras/migrations/0065_configcontext_data_migrations.py +44 -0
  403. nautobot/extras/migrations/{0065_rename_configcontext_role.py → 0066_rename_configcontext_role.py} +1 -2
  404. nautobot/extras/migrations/{0066_jobresult__add_celery_fields.py → 0067_jobresult__add_celery_fields.py} +36 -3
  405. nautobot/extras/migrations/{0067_created_datetime.py → 0068_created_datetime.py} +1 -2
  406. nautobot/extras/migrations/{0068_remove_site_and_region_attributes_from_config_context.py → 0069_remove_site_and_region_attributes_from_config_context.py} +1 -2
  407. nautobot/extras/migrations/{0069_replace_related_names.py → 0070_replace_related_names.py} +1 -1
  408. nautobot/extras/migrations/{0070_rename_model_fields.py → 0071_rename_model_fields.py} +1 -2
  409. nautobot/extras/migrations/0072_job__unique_name_data_migration.py +86 -0
  410. nautobot/extras/migrations/{0072_job__unique_name.py → 0073_job__unique_name.py} +13 -10
  411. nautobot/extras/migrations/{0073_remove_gitrepository_fields.py → 0074_remove_gitrepository_fields.py} +1 -2
  412. nautobot/extras/migrations/{0074_rename_slug_to_key_for_custom_field.py → 0075_rename_slug_to_key_for_custom_field.py} +1 -1
  413. nautobot/extras/migrations/{0075_migrate_custom_field_data.py → 0076_migrate_custom_field_data.py} +1 -1
  414. nautobot/extras/migrations/{0076_remove_name_field_and_make_label_field_non_nullable.py → 0077_remove_name_field_and_make_label_field_non_nullable.py} +1 -1
  415. nautobot/extras/migrations/0078_remove_slug.py +45 -0
  416. nautobot/extras/migrations/0079_tagsfield.py +28 -0
  417. nautobot/extras/migrations/0080_rename_relationship_slug_to_key.py +17 -0
  418. nautobot/extras/migrations/0081_rename_relationship_name_to_label.py +29 -0
  419. nautobot/extras/migrations/0082_ensure_relationship_keys_are_unique.py +43 -0
  420. nautobot/extras/migrations/0083_rename_computed_field_slug_to_key.py +21 -0
  421. nautobot/extras/migrations/0084_taggeditem_cleanup.py +43 -0
  422. nautobot/extras/migrations/0085_taggeditem_uniqueness.py +22 -0
  423. nautobot/extras/migrations/0086_job__celery_task_fields__dryrun_support.py +81 -0
  424. nautobot/extras/migrations/0087_job__commit_default_data_migration.py +26 -0
  425. nautobot/extras/migrations/0088_joblogentry__log_level_default.py +17 -0
  426. nautobot/extras/migrations/0089_joblogentry__log_level_data_migration.py +34 -0
  427. nautobot/extras/migrations/0090_scheduledjob__data_migration.py +57 -0
  428. nautobot/extras/models/__init__.py +2 -3
  429. nautobot/extras/models/change_logging.py +0 -36
  430. nautobot/extras/models/customfields.py +39 -33
  431. nautobot/extras/models/datasources.py +48 -50
  432. nautobot/extras/models/groups.py +5 -12
  433. nautobot/extras/models/jobs.py +190 -323
  434. nautobot/extras/models/mixins.py +0 -71
  435. nautobot/extras/models/models.py +1 -22
  436. nautobot/extras/models/relationships.py +20 -21
  437. nautobot/extras/models/roles.py +0 -23
  438. nautobot/extras/models/secrets.py +2 -31
  439. nautobot/extras/models/statuses.py +6 -5
  440. nautobot/extras/models/tags.py +2 -17
  441. nautobot/extras/navigation.py +89 -307
  442. nautobot/extras/plugins/__init__.py +3 -121
  443. nautobot/extras/plugins/utils.py +0 -3
  444. nautobot/extras/plugins/validators.py +5 -4
  445. nautobot/extras/plugins/views.py +16 -4
  446. nautobot/extras/querysets.py +1 -7
  447. nautobot/extras/registry.py +3 -0
  448. nautobot/extras/signals.py +26 -60
  449. nautobot/extras/tables.py +42 -49
  450. nautobot/extras/tasks.py +0 -12
  451. nautobot/extras/templates/extras/configcontext.html +1 -1
  452. nautobot/extras/templates/extras/configcontextschema.html +16 -1
  453. nautobot/extras/templates/extras/customfield.html +0 -13
  454. nautobot/extras/templates/extras/dynamicgroup_edit.html +0 -1
  455. nautobot/extras/templates/extras/gitrepository.html +3 -3
  456. nautobot/extras/templates/extras/inc/jobresult.html +10 -0
  457. nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
  458. nautobot/extras/templates/extras/job.html +35 -25
  459. nautobot/extras/templates/extras/job_approval_request.html +15 -30
  460. nautobot/extras/templates/extras/job_detail.html +13 -31
  461. nautobot/extras/templates/extras/job_edit.html +14 -17
  462. nautobot/extras/templates/extras/jobresult.html +24 -6
  463. nautobot/extras/templates/extras/objectchange_list.html +1 -1
  464. nautobot/extras/templates/extras/scheduledjob.html +2 -2
  465. nautobot/extras/templates/extras/secret.html +28 -0
  466. nautobot/extras/templates/extras/secret_edit.html +0 -1
  467. nautobot/extras/templates/extras/secretsgroup_edit.html +0 -1
  468. nautobot/extras/templatetags/custom_links.py +0 -2
  469. nautobot/extras/templatetags/job_buttons.py +1 -0
  470. nautobot/extras/templatetags/plugins.py +0 -1
  471. nautobot/extras/{tests/example_jobs → test_jobs}/api_test_job.py +13 -6
  472. nautobot/extras/test_jobs/atomic_transaction.py +53 -0
  473. nautobot/extras/test_jobs/dry_run.py +29 -0
  474. nautobot/extras/{tests/example_jobs/test_duplicate_name.py → test_jobs/duplicate_name.py} +4 -0
  475. nautobot/extras/test_jobs/duplicate_name2.py +9 -0
  476. nautobot/extras/test_jobs/fail.py +23 -0
  477. nautobot/extras/{tests/example_jobs/test_field_default.py → test_jobs/field_default.py} +4 -0
  478. nautobot/extras/{tests/example_jobs/test_field_order.py → test_jobs/field_order.py} +4 -0
  479. nautobot/extras/{tests/example_jobs/test_file_upload_fail.py → test_jobs/file_upload_fail.py} +11 -6
  480. nautobot/extras/test_jobs/file_upload_pass.py +25 -0
  481. nautobot/extras/test_jobs/has_sensitive_variables.py +25 -0
  482. nautobot/extras/test_jobs/ipaddress_vars.py +66 -0
  483. nautobot/extras/test_jobs/job_button_receiver.py +28 -0
  484. nautobot/extras/test_jobs/job_hook_receiver.py +29 -0
  485. nautobot/extras/test_jobs/job_variables.py +88 -0
  486. nautobot/extras/test_jobs/location_with_custom_field.py +45 -0
  487. nautobot/extras/test_jobs/log_redaction.py +20 -0
  488. nautobot/extras/test_jobs/log_skip_db_logging.py +17 -0
  489. nautobot/extras/test_jobs/modify_db.py +25 -0
  490. nautobot/extras/{tests/example_jobs/test_no_field_order.py → test_jobs/no_field_order.py} +4 -0
  491. nautobot/extras/test_jobs/object_var_optional.py +21 -0
  492. nautobot/extras/test_jobs/object_var_required.py +21 -0
  493. nautobot/extras/test_jobs/object_vars.py +26 -0
  494. nautobot/extras/test_jobs/pass.py +25 -0
  495. nautobot/extras/test_jobs/profiling.py +32 -0
  496. nautobot/extras/test_jobs/read_only_job.py +15 -0
  497. nautobot/extras/{tests/example_jobs/test_required_args.py → test_jobs/required_args.py} +4 -0
  498. nautobot/extras/{tests/example_jobs/test_soft_time_limit_greater_than_time_limit.py → test_jobs/soft_time_limit_greater_than_time_limit.py} +5 -1
  499. nautobot/extras/{tests/example_jobs/test_task_queues.py → test_jobs/task_queues.py} +5 -1
  500. nautobot/extras/tests/integration/__init__.py +3 -3
  501. nautobot/extras/tests/integration/test_computedfields.py +1 -1
  502. nautobot/extras/tests/integration/test_configcontextschema.py +7 -5
  503. nautobot/extras/tests/integration/test_customfields.py +4 -2
  504. nautobot/extras/tests/integration/test_dynamicgroups.py +2 -2
  505. nautobot/extras/tests/integration/test_jobs.py +25 -27
  506. nautobot/extras/tests/integration/test_notes.py +8 -4
  507. nautobot/extras/tests/integration/test_plugins.py +4 -4
  508. nautobot/extras/tests/integration/test_relationships.py +2 -2
  509. nautobot/extras/tests/test_api.py +371 -381
  510. nautobot/extras/tests/test_changelog.py +17 -16
  511. nautobot/extras/tests/test_context_managers.py +5 -6
  512. nautobot/extras/tests/test_customfields.py +112 -73
  513. nautobot/extras/tests/test_datasources.py +191 -117
  514. nautobot/extras/tests/test_dynamicgroups.py +45 -68
  515. nautobot/extras/tests/test_filters.py +170 -130
  516. nautobot/extras/tests/test_forms.py +107 -109
  517. nautobot/extras/tests/{test_scripts.py → test_job_variables.py} +43 -49
  518. nautobot/extras/tests/test_jobs.py +271 -273
  519. nautobot/extras/tests/test_management.py +3 -6
  520. nautobot/extras/tests/test_migrations.py +5 -3
  521. nautobot/extras/tests/test_models.py +121 -173
  522. nautobot/extras/tests/test_notes.py +0 -1
  523. nautobot/extras/tests/test_plugins.py +55 -89
  524. nautobot/extras/tests/test_relationships.py +174 -130
  525. nautobot/extras/tests/test_tags.py +6 -12
  526. nautobot/extras/tests/test_utils.py +31 -1
  527. nautobot/extras/tests/test_views.py +223 -184
  528. nautobot/extras/tests/test_webhooks.py +16 -15
  529. nautobot/extras/urls.py +69 -69
  530. nautobot/extras/utils.py +137 -163
  531. nautobot/extras/views.py +81 -153
  532. nautobot/ipam/api/fields.py +17 -0
  533. nautobot/ipam/api/serializers.py +77 -164
  534. nautobot/ipam/api/urls.py +4 -1
  535. nautobot/ipam/api/views.py +28 -19
  536. nautobot/ipam/apps.py +1 -0
  537. nautobot/ipam/choices.py +5 -12
  538. nautobot/ipam/constants.py +1 -0
  539. nautobot/ipam/factory.py +41 -30
  540. nautobot/ipam/filters.py +58 -25
  541. nautobot/ipam/forms.py +82 -211
  542. nautobot/ipam/graphql/types.py +0 -9
  543. nautobot/ipam/lookups.py +13 -8
  544. nautobot/ipam/management/commands/__init__.py +0 -0
  545. nautobot/ipam/management/commands/fix_prefix_broadcast.py +17 -0
  546. nautobot/ipam/migrations/0001_initial_part_1.py +0 -1
  547. nautobot/ipam/migrations/0002_initial_part_2.py +0 -1
  548. nautobot/ipam/migrations/0003_remove_max_length.py +0 -1
  549. nautobot/ipam/migrations/0004_fixup_p2p_broadcast.py +0 -1
  550. nautobot/ipam/migrations/0005_auto_slug.py +0 -1
  551. nautobot/ipam/migrations/0006_ipaddress_nat_outside_list.py +0 -1
  552. nautobot/ipam/migrations/0007_add_natural_indexing.py +0 -1
  553. nautobot/ipam/migrations/0008_prefix_vlan_vlangroup_location.py +0 -1
  554. nautobot/ipam/migrations/0009_alter_vlan_name.py +0 -1
  555. nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -2
  556. nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +32 -39
  557. nautobot/ipam/migrations/0012_rename_ipam_roles.py +0 -1
  558. nautobot/ipam/migrations/0013_delete_role.py +0 -1
  559. nautobot/ipam/migrations/0014_rename_foreign_keys_and_related_names.py +0 -1
  560. nautobot/ipam/migrations/0015_prefix_add_type.py +0 -1
  561. nautobot/ipam/migrations/0016_prefix_type_data_migration.py +0 -3
  562. nautobot/ipam/migrations/0017_prefix_remove_is_pool.py +0 -1
  563. nautobot/ipam/migrations/0018_remove_site_foreign_key_from_ipam_models.py +0 -1
  564. nautobot/ipam/migrations/0019_created_datetime.py +0 -1
  565. nautobot/ipam/migrations/0020_related_name_changes.py +1 -2
  566. nautobot/ipam/migrations/0021_prefix_add_rir_and_date_allocated.py +0 -1
  567. nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +3 -5
  568. nautobot/ipam/migrations/0023_delete_aggregate.py +0 -1
  569. nautobot/ipam/migrations/0024_interface_to_ipaddress_m2m.py +0 -1
  570. nautobot/ipam/migrations/0025_interface_ipaddress_m2m_data_migration.py +0 -1
  571. nautobot/ipam/migrations/0026_ipaddress_remove_assigned_object.py +0 -1
  572. nautobot/ipam/migrations/0027_remove_rir_slug.py +16 -0
  573. nautobot/ipam/migrations/0028_tagsfield.py +44 -0
  574. nautobot/ipam/migrations/0029_ip_address_to_interface_uniqueness_constraints.py +18 -0
  575. nautobot/ipam/migrations/0030_ipam__namespaces.py +231 -0
  576. nautobot/ipam/migrations/0031_ipam__prefix__add_parent.py +58 -0
  577. nautobot/ipam/migrations/0032_ipam__namespaces_finish.py +63 -0
  578. nautobot/ipam/migrations/0033_fixup_null_statuses.py +26 -0
  579. nautobot/ipam/migrations/0034_status_nonnullable.py +36 -0
  580. nautobot/ipam/models.py +579 -368
  581. nautobot/ipam/navigation.py +36 -159
  582. nautobot/ipam/querysets.py +117 -90
  583. nautobot/ipam/signals.py +89 -0
  584. nautobot/ipam/tables.py +86 -28
  585. nautobot/ipam/templates/ipam/ipaddress.html +14 -30
  586. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -0
  587. nautobot/ipam/templates/ipam/namespace_ipaddresses.html +11 -0
  588. nautobot/ipam/templates/ipam/namespace_prefixes.html +11 -0
  589. nautobot/ipam/templates/ipam/namespace_retrieve.html +42 -0
  590. nautobot/ipam/templates/ipam/namespace_vrfs.html +11 -0
  591. nautobot/ipam/templates/ipam/prefix.html +27 -33
  592. nautobot/ipam/templates/ipam/prefix_edit.html +7 -1
  593. nautobot/ipam/templates/ipam/vlangroup.html +0 -13
  594. nautobot/ipam/templates/ipam/vrf.html +6 -4
  595. nautobot/ipam/templates/ipam/vrf_edit.html +20 -2
  596. nautobot/ipam/tests/integration/test_prefixes.py +4 -27
  597. nautobot/ipam/tests/test_api.py +60 -61
  598. nautobot/ipam/tests/test_filters.py +187 -126
  599. nautobot/ipam/tests/test_forms.py +12 -6
  600. nautobot/ipam/tests/test_graphql.py +8 -6
  601. nautobot/ipam/tests/test_migrations.py +8 -13
  602. nautobot/ipam/tests/test_models.py +426 -274
  603. nautobot/ipam/tests/test_ordering.py +6 -3
  604. nautobot/ipam/tests/test_querysets.py +340 -96
  605. nautobot/ipam/tests/test_views.py +100 -55
  606. nautobot/ipam/urls.py +28 -5
  607. nautobot/ipam/{utils.py → utils/__init__.py} +2 -2
  608. nautobot/ipam/utils/migrations.py +713 -0
  609. nautobot/ipam/views.py +237 -122
  610. nautobot/project-static/docs/404.html +1399 -166
  611. nautobot/project-static/docs/additional-features/caching.html +1416 -320
  612. nautobot/project-static/docs/additional-features/change-logging.html +1389 -190
  613. nautobot/project-static/docs/additional-features/config-contexts.html +1389 -190
  614. nautobot/project-static/docs/additional-features/graphql.html +1389 -190
  615. nautobot/project-static/docs/additional-features/healthcheck.html +1389 -190
  616. nautobot/project-static/docs/additional-features/job-scheduling-and-approvals.html +1393 -190
  617. nautobot/project-static/docs/additional-features/jobs.html +1677 -460
  618. nautobot/project-static/docs/additional-features/napalm.html +1389 -190
  619. nautobot/project-static/docs/additional-features/prometheus-metrics.html +1389 -190
  620. nautobot/project-static/docs/additional-features/template-filters.html +1389 -190
  621. nautobot/project-static/docs/administration/celery-queues.html +1389 -190
  622. nautobot/project-static/docs/administration/nautobot-server.html +1553 -375
  623. nautobot/project-static/docs/administration/nautobot-shell.html +1395 -196
  624. nautobot/project-static/docs/administration/permissions.html +1389 -190
  625. nautobot/project-static/docs/administration/replicating-nautobot.html +1387 -207
  626. nautobot/project-static/docs/apps/index.html +1389 -190
  627. nautobot/project-static/docs/apps/nautobot-apps.html +1387 -175
  628. nautobot/project-static/docs/assets/javascripts/bundle.51198bba.min.js +29 -0
  629. nautobot/project-static/docs/assets/javascripts/bundle.51198bba.min.js.map +8 -0
  630. nautobot/project-static/docs/assets/javascripts/workers/{search.16e2a7d4.min.js → search.208ed371.min.js} +9 -15
  631. nautobot/project-static/docs/assets/javascripts/workers/{search.16e2a7d4.min.js.map → search.208ed371.min.js.map} +4 -4
  632. nautobot/project-static/docs/assets/stylesheets/main.ded33207.min.css +1 -0
  633. nautobot/project-static/docs/assets/stylesheets/main.ded33207.min.css.map +1 -0
  634. nautobot/project-static/docs/assets/stylesheets/palette.a0c5b2b5.min.css +1 -0
  635. nautobot/project-static/docs/assets/stylesheets/palette.a0c5b2b5.min.css.map +1 -0
  636. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +1775 -590
  637. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +1389 -190
  638. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +3588 -1922
  639. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +1461 -262
  640. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +1401 -170
  641. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +1396 -191
  642. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2095 -894
  643. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2357 -1194
  644. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2258 -940
  645. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +1389 -190
  646. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1400 -201
  647. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +11068 -7861
  648. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2867 -2224
  649. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +1389 -190
  650. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2641 -1573
  651. nautobot/project-static/docs/configuration/authentication/ldap.html +1389 -190
  652. nautobot/project-static/docs/configuration/authentication/remote.html +1389 -190
  653. nautobot/project-static/docs/configuration/authentication/sso.html +1389 -190
  654. nautobot/project-static/docs/configuration/index.html +1398 -199
  655. nautobot/project-static/docs/configuration/optional-settings.html +1418 -274
  656. nautobot/project-static/docs/configuration/required-settings.html +1419 -287
  657. nautobot/project-static/docs/core-functionality/circuits.html +1446 -247
  658. nautobot/project-static/docs/core-functionality/device-types.html +1448 -249
  659. nautobot/project-static/docs/core-functionality/devices.html +1452 -249
  660. nautobot/project-static/docs/core-functionality/ipam.html +1452 -253
  661. nautobot/project-static/docs/core-functionality/power.html +1448 -249
  662. nautobot/project-static/docs/core-functionality/secrets.html +1448 -249
  663. nautobot/project-static/docs/core-functionality/services.html +1448 -249
  664. nautobot/project-static/docs/core-functionality/sites-and-racks.html +1448 -249
  665. nautobot/project-static/docs/core-functionality/tenancy.html +1448 -249
  666. nautobot/project-static/docs/core-functionality/virtualization.html +1452 -249
  667. nautobot/project-static/docs/core-functionality/vlans.html +1448 -249
  668. nautobot/project-static/docs/development/application-registry.html +1393 -214
  669. nautobot/project-static/docs/development/best-practices.html +1392 -192
  670. nautobot/project-static/docs/development/docker-compose-advanced-use-cases.html +1390 -191
  671. nautobot/project-static/docs/development/extending-models.html +1443 -257
  672. nautobot/project-static/docs/development/generic-views.html +1403 -174
  673. nautobot/project-static/docs/development/getting-started.html +1568 -262
  674. nautobot/project-static/docs/development/homepage.html +1389 -190
  675. nautobot/project-static/docs/development/index.html +1389 -190
  676. nautobot/project-static/docs/development/model-features.html +1389 -190
  677. nautobot/project-static/docs/development/natural-keys.html +1389 -190
  678. nautobot/project-static/docs/development/navigation-menu.html +1451 -330
  679. nautobot/project-static/docs/development/react-ui.html +4199 -0
  680. nautobot/project-static/docs/development/release-checklist.html +1392 -193
  681. nautobot/project-static/docs/development/role-internals.html +1402 -172
  682. nautobot/project-static/docs/development/style-guide.html +1399 -199
  683. nautobot/project-static/docs/development/templates.html +1391 -191
  684. nautobot/project-static/docs/development/testing.html +1389 -190
  685. nautobot/project-static/docs/development/user-preferences.html +1389 -190
  686. nautobot/project-static/docs/docker/index.html +1408 -206
  687. nautobot/project-static/docs/index.html +1397 -180
  688. nautobot/project-static/docs/installation/centos.html +1401 -170
  689. nautobot/project-static/docs/installation/external-authentication.html +1389 -190
  690. nautobot/project-static/docs/installation/http-server.html +1389 -190
  691. nautobot/project-static/docs/installation/index.html +1394 -191
  692. nautobot/project-static/docs/installation/migrating-from-netbox.html +1452 -305
  693. nautobot/project-static/docs/installation/migrating-from-postgresql.html +1390 -191
  694. nautobot/project-static/docs/installation/nautobot.html +1390 -191
  695. nautobot/project-static/docs/installation/region-and-site-data-migration-guide.html +1389 -190
  696. nautobot/project-static/docs/installation/selinux-troubleshooting.html +1401 -170
  697. nautobot/project-static/docs/installation/services.html +1389 -190
  698. nautobot/project-static/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
  699. nautobot/project-static/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
  700. nautobot/project-static/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
  701. nautobot/project-static/docs/installation/tables/v2-code-location-changes.yaml +241 -0
  702. nautobot/project-static/docs/installation/tables/v2-code-removals.yaml +67 -0
  703. nautobot/project-static/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
  704. nautobot/project-static/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
  705. nautobot/project-static/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
  706. nautobot/project-static/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
  707. nautobot/project-static/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
  708. nautobot/project-static/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
  709. nautobot/project-static/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
  710. nautobot/project-static/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
  711. nautobot/project-static/docs/installation/ubuntu.html +1401 -170
  712. nautobot/project-static/docs/installation/upgrading-from-nautobot-v1.html +4254 -1923
  713. nautobot/project-static/docs/installation/upgrading.html +1395 -192
  714. nautobot/project-static/docs/models/circuits/circuit.html +1427 -174
  715. nautobot/project-static/docs/models/circuits/circuittermination.html +1427 -174
  716. nautobot/project-static/docs/models/circuits/circuittype.html +1427 -174
  717. nautobot/project-static/docs/models/circuits/provider.html +1427 -174
  718. nautobot/project-static/docs/models/circuits/providernetwork.html +1427 -174
  719. nautobot/project-static/docs/models/dcim/cable.html +1458 -174
  720. nautobot/project-static/docs/models/dcim/consoleport.html +1427 -174
  721. nautobot/project-static/docs/models/dcim/consoleporttemplate.html +1427 -174
  722. nautobot/project-static/docs/models/dcim/consoleserverport.html +1427 -174
  723. nautobot/project-static/docs/models/dcim/consoleserverporttemplate.html +1427 -174
  724. nautobot/project-static/docs/models/dcim/device.html +1431 -174
  725. nautobot/project-static/docs/models/dcim/devicebay.html +1427 -174
  726. nautobot/project-static/docs/models/dcim/devicebaytemplate.html +1427 -174
  727. nautobot/project-static/docs/models/dcim/deviceredundancygroup.html +1522 -177
  728. nautobot/project-static/docs/models/dcim/devicetype.html +1427 -174
  729. nautobot/project-static/docs/models/dcim/frontport.html +1427 -174
  730. nautobot/project-static/docs/models/dcim/frontporttemplate.html +1427 -174
  731. nautobot/project-static/docs/models/dcim/interface.html +1427 -174
  732. nautobot/project-static/docs/models/dcim/interfacetemplate.html +1427 -174
  733. nautobot/project-static/docs/models/dcim/inventoryitem.html +1427 -174
  734. nautobot/project-static/docs/models/dcim/location.html +1427 -174
  735. nautobot/project-static/docs/models/dcim/locationtype.html +1427 -174
  736. nautobot/project-static/docs/models/dcim/manufacturer.html +1427 -174
  737. nautobot/project-static/docs/models/dcim/platform.html +1427 -174
  738. nautobot/project-static/docs/models/dcim/powerfeed.html +1425 -172
  739. nautobot/project-static/docs/models/dcim/poweroutlet.html +1427 -174
  740. nautobot/project-static/docs/models/dcim/poweroutlettemplate.html +1427 -174
  741. nautobot/project-static/docs/models/dcim/powerpanel.html +1425 -172
  742. nautobot/project-static/docs/models/dcim/powerport.html +1427 -174
  743. nautobot/project-static/docs/models/dcim/powerporttemplate.html +1427 -174
  744. nautobot/project-static/docs/models/dcim/rack.html +1427 -174
  745. nautobot/project-static/docs/models/dcim/rackgroup.html +1427 -174
  746. nautobot/project-static/docs/models/dcim/rackreservation.html +1427 -174
  747. nautobot/project-static/docs/models/dcim/rearport.html +1427 -174
  748. nautobot/project-static/docs/models/dcim/rearporttemplate.html +1427 -174
  749. nautobot/project-static/docs/models/dcim/region.html +1401 -170
  750. nautobot/project-static/docs/models/dcim/site.html +1401 -170
  751. nautobot/project-static/docs/models/dcim/virtualchassis.html +1425 -172
  752. nautobot/project-static/docs/models/extras/computedfield.html +1393 -194
  753. nautobot/project-static/docs/models/extras/configcontext.html +1465 -174
  754. nautobot/project-static/docs/models/extras/configcontextschema.html +1421 -168
  755. nautobot/project-static/docs/models/extras/customfield.html +1389 -190
  756. nautobot/project-static/docs/models/extras/customlink.html +1389 -190
  757. nautobot/project-static/docs/models/extras/dynamicgroup.html +1398 -199
  758. nautobot/project-static/docs/models/extras/exporttemplate.html +1389 -190
  759. nautobot/project-static/docs/models/extras/gitrepository.html +1393 -190
  760. nautobot/project-static/docs/models/extras/graphqlquery.html +1469 -171
  761. nautobot/project-static/docs/models/extras/imageattachment.html +1434 -181
  762. nautobot/project-static/docs/models/extras/job.html +1411 -157
  763. nautobot/project-static/docs/models/extras/jobbutton.html +1410 -207
  764. nautobot/project-static/docs/models/extras/jobhook.html +1397 -194
  765. nautobot/project-static/docs/models/extras/joblogentry.html +1408 -155
  766. nautobot/project-static/docs/models/extras/jobresult.html +1417 -159
  767. nautobot/project-static/docs/models/extras/note.html +1389 -190
  768. nautobot/project-static/docs/models/extras/relationship.html +1391 -192
  769. nautobot/project-static/docs/models/extras/role.html +1495 -198
  770. nautobot/project-static/docs/models/extras/secret.html +1492 -201
  771. nautobot/project-static/docs/models/extras/secretsgroup.html +1410 -157
  772. nautobot/project-static/docs/models/extras/status.html +1381 -221
  773. nautobot/project-static/docs/models/extras/tag.html +1389 -190
  774. nautobot/project-static/docs/models/extras/webhook.html +1389 -190
  775. nautobot/project-static/docs/models/ipam/ipaddress.html +1488 -200
  776. nautobot/project-static/docs/models/ipam/prefix.html +1410 -157
  777. nautobot/project-static/docs/models/ipam/rir.html +1410 -157
  778. nautobot/project-static/docs/models/ipam/routetarget.html +1410 -157
  779. nautobot/project-static/docs/models/ipam/service.html +1410 -157
  780. nautobot/project-static/docs/models/ipam/vlan.html +1410 -157
  781. nautobot/project-static/docs/models/ipam/vlangroup.html +1410 -157
  782. nautobot/project-static/docs/models/ipam/vrf.html +1410 -161
  783. nautobot/project-static/docs/models/tenancy/tenant.html +1412 -159
  784. nautobot/project-static/docs/models/tenancy/tenantgroup.html +1412 -159
  785. nautobot/project-static/docs/models/users/objectpermission.html +1462 -171
  786. nautobot/project-static/docs/models/users/token.html +1410 -157
  787. nautobot/project-static/docs/models/virtualization/cluster.html +1410 -157
  788. nautobot/project-static/docs/models/virtualization/clustergroup.html +1410 -157
  789. nautobot/project-static/docs/models/virtualization/clustertype.html +1410 -157
  790. nautobot/project-static/docs/models/virtualization/virtualmachine.html +1414 -157
  791. nautobot/project-static/docs/models/virtualization/vminterface.html +1410 -157
  792. nautobot/project-static/docs/objects.inv +0 -0
  793. nautobot/project-static/docs/plugins/development.html +1916 -646
  794. nautobot/project-static/docs/plugins/index.html +1389 -190
  795. nautobot/project-static/docs/plugins/porting-from-netbox.html +1389 -190
  796. nautobot/project-static/docs/release-notes/index.html +1389 -190
  797. nautobot/project-static/docs/release-notes/version-1.0.html +1389 -190
  798. nautobot/project-static/docs/release-notes/version-1.1.html +1389 -190
  799. nautobot/project-static/docs/release-notes/version-1.2.html +1389 -190
  800. nautobot/project-static/docs/release-notes/version-1.3.html +1389 -190
  801. nautobot/project-static/docs/release-notes/version-1.4.html +1389 -190
  802. nautobot/project-static/docs/release-notes/version-1.5.html +2016 -397
  803. nautobot/project-static/docs/release-notes/version-2.0.html +1935 -287
  804. nautobot/project-static/docs/requirements.txt +5 -4
  805. nautobot/project-static/docs/rest-api/authentication.html +1389 -190
  806. nautobot/project-static/docs/rest-api/filtering.html +1389 -190
  807. nautobot/project-static/docs/rest-api/overview.html +2002 -576
  808. nautobot/project-static/docs/rest-api/ui-related-endpoints.html +4057 -0
  809. nautobot/project-static/docs/search/search_index.json +1 -1
  810. nautobot/project-static/docs/sitemap.xml +197 -187
  811. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  812. nautobot/project-static/docs/user-guides/custom-fields.html +1390 -191
  813. nautobot/project-static/docs/user-guides/getting-started/creating-devices.html +1392 -193
  814. nautobot/project-static/docs/user-guides/getting-started/index.html +1388 -189
  815. nautobot/project-static/docs/user-guides/getting-started/interfaces.html +1388 -189
  816. nautobot/project-static/docs/user-guides/getting-started/ipam.html +1386 -187
  817. nautobot/project-static/docs/user-guides/getting-started/platforms.html +1448 -249
  818. nautobot/project-static/docs/user-guides/getting-started/regions.html +1411 -212
  819. nautobot/project-static/docs/user-guides/getting-started/search-bar.html +1395 -196
  820. nautobot/project-static/docs/user-guides/getting-started/tenants.html +1448 -249
  821. nautobot/project-static/docs/user-guides/getting-started/vlans-and-vlan-groups.html +1448 -249
  822. nautobot/project-static/docs/user-guides/git-data-source.html +1405 -206
  823. nautobot/project-static/docs/user-guides/graphql.html +1402 -203
  824. nautobot/project-static/docs/user-guides/relationships.html +1448 -249
  825. nautobot/project-static/docs/user-guides/s3-django-storage.html +1448 -249
  826. nautobot/project-static/js/forms.js +16 -9
  827. nautobot/project-static/js/theme.js +5 -0
  828. nautobot/tenancy/api/serializers.py +4 -34
  829. nautobot/tenancy/api/urls.py +1 -1
  830. nautobot/tenancy/filters/__init__.py +9 -7
  831. nautobot/tenancy/filters/mixins.py +3 -2
  832. nautobot/tenancy/forms.py +3 -36
  833. nautobot/tenancy/migrations/0001_initial.py +0 -1
  834. nautobot/tenancy/migrations/0002_auto_slug.py +0 -1
  835. nautobot/tenancy/migrations/0003_mptt_to_tree_queries.py +0 -1
  836. nautobot/tenancy/migrations/0004_change_tree_manager_on_tree_models.py +0 -1
  837. nautobot/tenancy/migrations/0005_rename_foreign_keys_and_related_names.py +0 -1
  838. nautobot/tenancy/migrations/0006_created_datetime.py +0 -1
  839. nautobot/tenancy/migrations/0007_remove_tenant_tenantgroup_slug.py +20 -0
  840. nautobot/tenancy/migrations/0008_tagsfield.py +19 -0
  841. nautobot/tenancy/models.py +0 -30
  842. nautobot/tenancy/navigation.py +6 -39
  843. nautobot/tenancy/tables.py +4 -4
  844. nautobot/tenancy/templates/tenancy/tenant.html +12 -12
  845. nautobot/tenancy/templates/tenancy/tenant_edit.html +0 -1
  846. nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
  847. nautobot/tenancy/tests/test_api.py +1 -12
  848. nautobot/tenancy/tests/test_filters.py +20 -12
  849. nautobot/tenancy/tests/test_views.py +11 -29
  850. nautobot/tenancy/urls.py +10 -10
  851. nautobot/tenancy/views.py +0 -3
  852. nautobot/ui/.eslintignore +6 -0
  853. nautobot/ui/.gitignore +10 -0
  854. nautobot/ui/.prettierignore +9 -0
  855. nautobot/ui/.prettierrc +4 -0
  856. nautobot/ui/README.md +33 -0
  857. nautobot/ui/app_imports.js.j2 +7 -0
  858. nautobot/ui/craco.config.js +46 -0
  859. nautobot/ui/jsconfig-base.json +11 -0
  860. nautobot/ui/jsconfig.json +5 -0
  861. nautobot/ui/lib/nautobot-craco-alias-plugin.js +40 -0
  862. nautobot/ui/package-lock.json +21451 -0
  863. nautobot/ui/package.json +70 -0
  864. nautobot/ui/public/index.html +47 -0
  865. nautobot/ui/public/logo192.png +0 -0
  866. nautobot/ui/public/logo512.png +0 -0
  867. nautobot/ui/public/manifest.json +25 -0
  868. nautobot/ui/public/nautobot_logo.svg +131 -0
  869. nautobot/ui/public/robots.txt +3 -0
  870. nautobot/ui/src/App.js +71 -0
  871. nautobot/ui/src/components/AppFullWidthComponents.js +8 -0
  872. nautobot/ui/src/components/AppTab.js +40 -0
  873. nautobot/ui/src/components/Apps.js +60 -0
  874. nautobot/ui/src/components/HomeChangelogPanel.js +98 -0
  875. nautobot/ui/src/components/HomePanel.js +58 -0
  876. nautobot/ui/src/components/JobHistoryTable.js +78 -0
  877. nautobot/ui/src/components/Layout.js +53 -0
  878. nautobot/ui/src/components/LoadingWidget.js +25 -0
  879. nautobot/ui/src/components/Navbar.js +116 -0
  880. nautobot/ui/src/components/NotificationPopover.js +27 -0
  881. nautobot/ui/src/components/ObjectListTable.js +209 -0
  882. nautobot/ui/src/components/ReferenceDataTag.js +35 -0
  883. nautobot/ui/src/components/RouterButton.js +10 -0
  884. nautobot/ui/src/components/RouterLink.js +10 -0
  885. nautobot/ui/src/components/SidebarNav.js +147 -0
  886. nautobot/ui/src/components/Table.js +48 -0
  887. nautobot/ui/src/components/TableItem.js +71 -0
  888. nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +16 -0
  889. nautobot/ui/src/components/__tests__/AppTab.test.js +21 -0
  890. nautobot/ui/src/components/__tests__/Apps.test.js +14 -0
  891. nautobot/ui/src/components/__tests__/Layout.test.js +33 -0
  892. nautobot/ui/src/components/__tests__/Table.test.js +36 -0
  893. nautobot/ui/src/components/__tests__/TableItem.test.js +37 -0
  894. nautobot/ui/src/components/__tests__/paginator.test.js +43 -0
  895. nautobot/ui/src/components/__tests__/paginator_form.test.js +13 -0
  896. nautobot/ui/src/components/pagination.js +93 -0
  897. nautobot/ui/src/components/paginator.js +79 -0
  898. nautobot/ui/src/components/paginator_form.js +43 -0
  899. nautobot/ui/src/components/usePagination.js +57 -0
  900. nautobot/ui/src/constants/apiPath.js +10 -0
  901. nautobot/ui/src/constants/icons.js +15 -0
  902. nautobot/ui/src/constants/size.js +15 -0
  903. nautobot/ui/src/index.js +65 -0
  904. nautobot/ui/src/reportWebVitals.js +15 -0
  905. nautobot/ui/src/router.js +77 -0
  906. nautobot/ui/src/utils/api.js +131 -0
  907. nautobot/ui/src/utils/app-import.js +15 -0
  908. nautobot/ui/src/utils/color.js +15 -0
  909. nautobot/ui/src/utils/date.js +14 -0
  910. nautobot/ui/src/utils/index.js +15 -0
  911. nautobot/ui/src/utils/navigation.js +32 -0
  912. nautobot/ui/src/utils/session.js +64 -0
  913. nautobot/ui/src/utils/store.js +242 -0
  914. nautobot/ui/src/utils/string.js +6 -0
  915. nautobot/ui/src/utils/url.js +4 -0
  916. nautobot/ui/src/views/Home.js +138 -0
  917. nautobot/ui/src/views/InstalledApps.js +80 -0
  918. nautobot/ui/src/views/Login.js +48 -0
  919. nautobot/ui/src/views/Logout.js +20 -0
  920. nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +11 -0
  921. nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +107 -0
  922. nautobot/ui/src/views/__tests__/Login.test.js +15 -0
  923. nautobot/ui/src/views/generic/GenericView.js +142 -0
  924. nautobot/ui/src/views/generic/ObjectCreate.js +96 -0
  925. nautobot/ui/src/views/generic/ObjectList.js +127 -0
  926. nautobot/ui/src/views/generic/ObjectRetrieve.js +551 -0
  927. nautobot/users/admin.py +1 -1
  928. nautobot/users/api/serializers.py +51 -61
  929. nautobot/users/api/urls.py +1 -1
  930. nautobot/users/api/views.py +53 -2
  931. nautobot/users/migrations/0001_initial.py +0 -1
  932. nautobot/users/migrations/0002_token_ordering_by_created.py +0 -1
  933. nautobot/users/migrations/0003_alter_user_options.py +0 -1
  934. nautobot/users/migrations/0004_alter_user_managers.py +0 -1
  935. nautobot/users/tests/test_api.py +109 -28
  936. nautobot/users/tests/test_filters.py +0 -4
  937. nautobot/users/tests/test_models.py +0 -1
  938. nautobot/users/views.py +0 -7
  939. nautobot/virtualization/api/serializers.py +18 -132
  940. nautobot/virtualization/api/urls.py +1 -1
  941. nautobot/virtualization/api/views.py +1 -22
  942. nautobot/virtualization/choices.py +0 -2
  943. nautobot/virtualization/filters.py +12 -7
  944. nautobot/virtualization/forms.py +21 -117
  945. nautobot/virtualization/migrations/0001_initial.py +0 -1
  946. nautobot/virtualization/migrations/0002_virtualmachine_local_context_schema.py +0 -1
  947. nautobot/virtualization/migrations/0003_vminterface_verbose_name.py +0 -1
  948. nautobot/virtualization/migrations/0004_auto_slug.py +0 -1
  949. nautobot/virtualization/migrations/0005_add_natural_indexing.py +0 -1
  950. nautobot/virtualization/migrations/0006_vminterface_status.py +0 -1
  951. nautobot/virtualization/migrations/0007_vminterface_status_data_migration.py +0 -1
  952. nautobot/virtualization/migrations/0008_vminterface_parent.py +0 -1
  953. nautobot/virtualization/migrations/0009_cluster_location.py +0 -1
  954. nautobot/virtualization/migrations/0010_vminterface_mac_address_data_migration.py +0 -1
  955. nautobot/virtualization/migrations/0011_alter_vminterface_mac_address.py +0 -1
  956. nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -2
  957. nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +18 -12
  958. nautobot/virtualization/migrations/0014_rename_virtualmachine_roles.py +0 -1
  959. nautobot/virtualization/migrations/0015_rename_foreignkey_fields.py +1 -2
  960. nautobot/virtualization/migrations/0016_remove_site_foreign_key_from_cluster_class.py +0 -1
  961. nautobot/virtualization/migrations/0017_created_datetime.py +0 -1
  962. nautobot/virtualization/migrations/0018_related_name_changes.py +1 -2
  963. nautobot/virtualization/migrations/0019_vminterface_ip_addresses_m2m.py +0 -1
  964. nautobot/virtualization/migrations/0020_remove_clustergroup_clustertype_slug.py +20 -0
  965. nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +39 -0
  966. nautobot/virtualization/migrations/0022_vminterface_timestamps_data_migration.py +17 -0
  967. nautobot/virtualization/migrations/0023_ipam__namespaces.py +25 -0
  968. nautobot/virtualization/migrations/0024_fixup_null_statuses.py +25 -0
  969. nautobot/virtualization/migrations/0025_status_nonnullable.py +29 -0
  970. nautobot/virtualization/models.py +39 -131
  971. nautobot/virtualization/navigation.py +18 -99
  972. nautobot/virtualization/tables.py +4 -4
  973. nautobot/virtualization/templates/virtualization/virtualmachine.html +13 -2
  974. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +6 -0
  975. nautobot/virtualization/tests/test_api.py +42 -52
  976. nautobot/virtualization/tests/test_filters.py +98 -75
  977. nautobot/virtualization/tests/test_models.py +36 -13
  978. nautobot/virtualization/tests/test_views.py +68 -73
  979. nautobot/virtualization/urls.py +10 -10
  980. nautobot/virtualization/views.py +8 -14
  981. {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/METADATA +15 -22
  982. {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/RECORD +987 -834
  983. {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/WHEEL +1 -1
  984. nautobot/circuits/api/nested_serializers.py +0 -69
  985. nautobot/core/templates/plugin_template/navigation.py-tpl +0 -22
  986. nautobot/dcim/api/nested_serializers.py +0 -356
  987. nautobot/dcim/templates/dcim/device_import.html +0 -5
  988. nautobot/dcim/templates/dcim/device_import_child.html +0 -5
  989. nautobot/dcim/templates/dcim/inc/device_import_header.html +0 -4
  990. nautobot/extras/api/nested_serializers.py +0 -353
  991. nautobot/extras/migrations/0064_configcontext_data_migrations.py +0 -42
  992. nautobot/extras/migrations/0071_job__unique_name_data_migration.py +0 -47
  993. nautobot/extras/reports.py +0 -60
  994. nautobot/extras/scripts.py +0 -72
  995. nautobot/extras/tests/example_jobs/script_variables.py +0 -67
  996. nautobot/extras/tests/example_jobs/test_duplicate_name2.py +0 -5
  997. nautobot/extras/tests/example_jobs/test_fail.py +0 -16
  998. nautobot/extras/tests/example_jobs/test_file_upload_pass.py +0 -20
  999. nautobot/extras/tests/example_jobs/test_ipaddress_vars.py +0 -52
  1000. nautobot/extras/tests/example_jobs/test_job_button_receiver.py +0 -21
  1001. nautobot/extras/tests/example_jobs/test_job_hook_receiver.py +0 -20
  1002. nautobot/extras/tests/example_jobs/test_location_with_custom_field.py +0 -35
  1003. nautobot/extras/tests/example_jobs/test_log_redaction.py +0 -14
  1004. nautobot/extras/tests/example_jobs/test_modify_db.py +0 -19
  1005. nautobot/extras/tests/example_jobs/test_object_var_optional.py +0 -14
  1006. nautobot/extras/tests/example_jobs/test_object_var_required.py +0 -14
  1007. nautobot/extras/tests/example_jobs/test_object_vars.py +0 -29
  1008. nautobot/extras/tests/example_jobs/test_pass.py +0 -19
  1009. nautobot/extras/tests/example_jobs/test_read_only_fail.py +0 -24
  1010. nautobot/extras/tests/example_jobs/test_read_only_no_commit_field.py +0 -10
  1011. nautobot/extras/tests/example_jobs/test_read_only_pass.py +0 -22
  1012. nautobot/ipam/api/nested_serializers.py +0 -143
  1013. nautobot/project-static/docs/assets/javascripts/bundle.5a2dcb6a.min.js +0 -29
  1014. nautobot/project-static/docs/assets/javascripts/bundle.5a2dcb6a.min.js.map +0 -8
  1015. nautobot/project-static/docs/assets/javascripts/extra/bundle.5f09fbc3.min.js +0 -18
  1016. nautobot/project-static/docs/assets/javascripts/extra/bundle.5f09fbc3.min.js.map +0 -8
  1017. nautobot/project-static/docs/assets/stylesheets/extra.0d2c79a8.min.css +0 -1
  1018. nautobot/project-static/docs/assets/stylesheets/extra.0d2c79a8.min.css.map +0 -1
  1019. nautobot/project-static/docs/assets/stylesheets/main.975780f9.min.css +0 -1
  1020. nautobot/project-static/docs/assets/stylesheets/main.975780f9.min.css.map +0 -1
  1021. nautobot/project-static/docs/assets/stylesheets/palette.2505c338.min.css +0 -1
  1022. nautobot/project-static/docs/assets/stylesheets/palette.2505c338.min.css.map +0 -1
  1023. nautobot/tenancy/api/nested_serializers.py +0 -31
  1024. nautobot/users/api/nested_serializers.py +0 -67
  1025. nautobot/virtualization/api/nested_serializers.py +0 -65
  1026. /nautobot/extras/{tests/example_jobs → test_jobs}/__init__.py +0 -0
  1027. /nautobot/{dcim/models/sites.py → ipam/management/__init__.py} +0 -0
  1028. {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/LICENSE.txt +0 -0
  1029. {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/entry_points.txt +0 -0
@@ -89,7 +89,7 @@ from nautobot.dcim.models import (
89
89
  VirtualChassis,
90
90
  )
91
91
  from nautobot.extras.models import Role, SecretsGroup, Status, Tag
92
- from nautobot.ipam.models import IPAddress, Prefix, Service, VLAN, VLANGroup
92
+ from nautobot.ipam.models import IPAddress, Prefix, Service, VLAN, VLANGroup, Namespace
93
93
  from nautobot.tenancy.models import Tenant
94
94
  from nautobot.virtualization.models import Cluster, ClusterType, VirtualMachine
95
95
 
@@ -99,7 +99,6 @@ User = get_user_model()
99
99
 
100
100
 
101
101
  def common_test_data(cls):
102
-
103
102
  tenants = Tenant.objects.filter(tenant_group__isnull=False)
104
103
  cls.tenants = tenants
105
104
 
@@ -112,6 +111,9 @@ def common_test_data(cls):
112
111
  loc0 = Location.objects.filter(location_type=lt1).first()
113
112
  loc1 = Location.objects.filter(location_type=lt1).first()
114
113
  loc2 = Location.objects.filter(location_type=lt2).first()
114
+
115
+ for instance in [loc0, loc1]:
116
+ instance.tags.set(Tag.objects.get_for_model(Location))
115
117
  loc2.parent = loc1
116
118
  loc3 = Location.objects.filter(location_type=lt3).first()
117
119
  loc3.parent = loc2
@@ -123,41 +125,24 @@ def common_test_data(cls):
123
125
  cls.loc1 = loc1
124
126
  cls.nested_loc = nested_loc
125
127
 
126
- provider = Provider.objects.create(name="Provider 1", slug="provider-1", asn=65001, account="1234")
127
- circuit_type = CircuitType.objects.create(name="Test Circuit Type 1", slug="test-circuit-type-1")
128
- circuit = Circuit.objects.create(provider=provider, circuit_type=circuit_type, cid="Test Circuit 1")
128
+ provider = Provider.objects.first()
129
+ circuit_type = CircuitType.objects.first()
130
+ circuit_status = Status.objects.get_for_model(Circuit).first()
131
+ circuit = Circuit.objects.create(
132
+ provider=provider, circuit_type=circuit_type, cid="Test Circuit 1", status=circuit_status
133
+ )
129
134
  CircuitTermination.objects.create(circuit=circuit, location=loc0, term_side="A")
130
135
  CircuitTermination.objects.create(circuit=circuit, location=loc1, term_side="Z")
131
136
 
132
137
  manufacturers = list(Manufacturer.objects.all()[:3])
133
138
  cls.manufacturers = manufacturers
134
139
 
135
- platforms = (
136
- Platform.objects.create(
137
- name="Platform 1",
138
- slug="platform-1",
139
- manufacturer=manufacturers[0],
140
- napalm_driver="driver-1",
141
- napalm_args=["--test", "--arg1"],
142
- description="A",
143
- ),
144
- Platform.objects.create(
145
- name="Platform 2",
146
- slug="platform-2",
147
- manufacturer=manufacturers[1],
148
- napalm_driver="driver-2",
149
- napalm_args=["--test", "--arg2"],
150
- description="B",
151
- ),
152
- Platform.objects.create(
153
- name="Platform 3",
154
- slug="platform-3",
155
- manufacturer=manufacturers[2],
156
- napalm_driver="driver-3",
157
- napalm_args=["--test", "--arg3"],
158
- description="C",
159
- ),
160
- )
140
+ platforms = Platform.objects.all()[:3]
141
+ for num, platform in enumerate(platforms):
142
+ platform.napalm_driver = f"driver-{num}"
143
+ platform.napalm_args = ["--test", f"--arg{num}"]
144
+ platform.save()
145
+
161
146
  cls.platforms = platforms
162
147
 
163
148
  device_types = (
@@ -209,8 +194,7 @@ def common_test_data(cls):
209
194
 
210
195
  rackroles = Role.objects.get_for_model(Rack)
211
196
 
212
- rack_statuses = Status.objects.get_for_model(Rack)
213
- cls.rack_status_map = {s.slug: s for s in rack_statuses.all()}
197
+ cls.rack_statuses = Status.objects.get_for_model(Rack)
214
198
 
215
199
  racks = (
216
200
  Rack.objects.create(
@@ -220,7 +204,7 @@ def common_test_data(cls):
220
204
  location=loc0,
221
205
  rack_group=rack_groups[0],
222
206
  tenant=tenants[0],
223
- status=cls.rack_status_map["active"],
207
+ status=cls.rack_statuses[0],
224
208
  role=rackroles[0],
225
209
  serial="ABC",
226
210
  asset_tag="1001",
@@ -239,7 +223,7 @@ def common_test_data(cls):
239
223
  rack_group=rack_groups[1],
240
224
  location=loc0,
241
225
  tenant=tenants[1],
242
- status=cls.rack_status_map["planned"],
226
+ status=cls.rack_statuses[1],
243
227
  role=rackroles[1],
244
228
  serial="DEF",
245
229
  asset_tag="1002",
@@ -258,7 +242,7 @@ def common_test_data(cls):
258
242
  rack_group=rack_groups[2],
259
243
  location=loc0,
260
244
  tenant=tenants[2],
261
- status=cls.rack_status_map["reserved"],
245
+ status=cls.rack_statuses[2],
262
246
  role=rackroles[2],
263
247
  serial="GHI",
264
248
  asset_tag="1003",
@@ -276,34 +260,44 @@ def common_test_data(cls):
276
260
 
277
261
  cls.device_roles = Role.objects.get_for_model(Device)
278
262
 
279
- cluster_type = ClusterType.objects.create(name="Cluster Type 1", slug="cluster-type-1")
263
+ cluster_type = ClusterType.objects.create(name="Circuit Type 2")
280
264
  clusters = (
281
265
  Cluster.objects.create(name="Cluster 1", cluster_type=cluster_type, location=loc0),
282
266
  Cluster.objects.create(name="Cluster 2", cluster_type=cluster_type, location=loc1),
283
267
  Cluster.objects.create(name="Cluster 3", cluster_type=cluster_type, location=loc1),
284
268
  )
285
269
 
286
- VirtualMachine.objects.create(cluster=clusters[0], name="VM 1", role=cls.device_roles[0], platform=platforms[0])
287
- VirtualMachine.objects.create(cluster=clusters[0], name="VM 2", role=cls.device_roles[1], platform=platforms[1])
288
- VirtualMachine.objects.create(cluster=clusters[0], name="VM 3", role=cls.device_roles[2], platform=platforms[2])
270
+ vm_status = Status.objects.get_for_model(VirtualMachine).first()
271
+ VirtualMachine.objects.create(
272
+ cluster=clusters[0], name="VM 1", role=cls.device_roles[0], platform=platforms[0], status=vm_status
273
+ )
274
+ VirtualMachine.objects.create(
275
+ cluster=clusters[0], name="VM 2", role=cls.device_roles[1], platform=platforms[1], status=vm_status
276
+ )
277
+ VirtualMachine.objects.create(
278
+ cluster=clusters[0], name="VM 3", role=cls.device_roles[2], platform=platforms[2], status=vm_status
279
+ )
289
280
 
290
- Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.0.0/16"), location=loc0)
291
- Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.1.0/24"), location=loc0)
292
- Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.2.0/24"), location=loc1)
281
+ prefix_status = Status.objects.get_for_model(Prefix).first()
282
+ Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.0.0/16"), location=loc0, status=prefix_status)
283
+ Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.1.0/24"), location=loc0, status=prefix_status)
284
+ Prefix.objects.create(prefix=netaddr.IPNetwork("192.168.2.0/24"), location=loc1, status=prefix_status)
293
285
 
294
286
  # TODO: remove these once we have a Sites fixture; for now SiteTestCase needs VLANGroups and VLANs with Sites
295
287
  VLANGroup.objects.create(name="VLAN Group 1", slug="vlan-group-1", location=loc0)
296
288
  VLANGroup.objects.create(name="VLAN Group 2", slug="vlan-group-2", location=loc0)
297
289
  VLANGroup.objects.create(name="VLAN Group 3", slug="vlan-group-3", location=loc1)
298
290
 
299
- VLAN.objects.create(name="VLAN 101", vid=101, location=loc0)
300
- VLAN.objects.create(name="VLAN 102", vid=102, location=loc0)
301
- VLAN.objects.create(name="VLAN 103", vid=103, location=loc1)
291
+ vlan_status = Status.objects.get_for_model(VLAN).first()
292
+ VLAN.objects.create(name="VLAN 101", vid=101, location=loc0, status=vlan_status)
293
+ VLAN.objects.create(name="VLAN 102", vid=102, location=loc0, status=vlan_status)
294
+ VLAN.objects.create(name="VLAN 103", vid=103, location=loc1, status=vlan_status)
302
295
 
296
+ pf_status = Status.objects.get_for_model(PowerFeed).first()
303
297
  power_feeds = (
304
- PowerFeed.objects.create(name="Power Feed 1", rack=racks[0], power_panel=power_panels[0]),
305
- PowerFeed.objects.create(name="Power Feed 2", rack=racks[1], power_panel=power_panels[1]),
306
- PowerFeed.objects.create(name="Power Feed 3", rack=racks[2], power_panel=power_panels[2]),
298
+ PowerFeed.objects.create(name="Power Feed 1", rack=racks[0], power_panel=power_panels[0], status=pf_status),
299
+ PowerFeed.objects.create(name="Power Feed 2", rack=racks[1], power_panel=power_panels[1], status=pf_status),
300
+ PowerFeed.objects.create(name="Power Feed 3", rack=racks[2], power_panel=power_panels[2], status=pf_status),
307
301
  )
308
302
  power_feeds[0].tags.set(Tag.objects.get_for_model(PowerFeed))
309
303
  power_feeds[1].tags.set(Tag.objects.get_for_model(PowerFeed)[:3])
@@ -530,13 +524,12 @@ def common_test_data(cls):
530
524
  )
531
525
 
532
526
  secrets_groups = (
533
- SecretsGroup.objects.create(name="Secrets group 1", slug="secrets-group-1"),
534
- SecretsGroup.objects.create(name="Secrets group 2", slug="secrets-group-2"),
535
- SecretsGroup.objects.create(name="Secrets group 3", slug="secrets-group-3"),
527
+ SecretsGroup.objects.create(name="Secrets group 1"),
528
+ SecretsGroup.objects.create(name="Secrets group 2"),
529
+ SecretsGroup.objects.create(name="Secrets group 3"),
536
530
  )
537
531
 
538
532
  device_statuses = Status.objects.get_for_model(Device)
539
- device_status_map = {ds.slug: ds for ds in device_statuses.all()}
540
533
 
541
534
  devices = (
542
535
  Device.objects.create(
@@ -547,7 +540,7 @@ def common_test_data(cls):
547
540
  rack=racks[0],
548
541
  location=loc0,
549
542
  tenant=tenants[0],
550
- status=device_status_map["active"],
543
+ status=device_statuses[0],
551
544
  cluster=clusters[0],
552
545
  asset_tag="1001",
553
546
  face=DeviceFaceChoices.FACE_FRONT,
@@ -563,7 +556,7 @@ def common_test_data(cls):
563
556
  rack=racks[1],
564
557
  location=loc0,
565
558
  tenant=tenants[1],
566
- status=device_status_map["staged"],
559
+ status=device_statuses[1],
567
560
  cluster=clusters[1],
568
561
  asset_tag="1002",
569
562
  face=DeviceFaceChoices.FACE_FRONT,
@@ -580,7 +573,7 @@ def common_test_data(cls):
580
573
  rack=racks[2],
581
574
  location=loc1,
582
575
  tenant=tenants[2],
583
- status=device_status_map["failed"],
576
+ status=device_statuses[2],
584
577
  cluster=clusters[2],
585
578
  asset_tag="1003",
586
579
  face=DeviceFaceChoices.FACE_REAR,
@@ -661,7 +654,7 @@ class LocationFilterSetTestCase(FilterTestCases.NameSlugFilterTestCase, FilterTe
661
654
  ("racks", "racks__id"),
662
655
  ("racks", "racks__name"),
663
656
  ("shipping_address",),
664
- ("status", "status__slug"),
657
+ ("status", "status__name"),
665
658
  ("time_zone",),
666
659
  ("vlan_groups", "vlan_groups__id"),
667
660
  ("vlan_groups", "vlan_groups__slug"),
@@ -778,9 +771,9 @@ class RackTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilter
778
771
  ("rack_group", "rack_group__id"),
779
772
  ("rack_group", "rack_group__slug"),
780
773
  ("rack_reservations", "rack_reservations__id"),
781
- ("role", "role__slug"),
774
+ ("role", "role__name"),
782
775
  ("serial",),
783
- ("status", "status__slug"),
776
+ ("status", "status__name"),
784
777
  ("type",),
785
778
  ("u_height",),
786
779
  ("width",),
@@ -800,7 +793,7 @@ class RackTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilter
800
793
  location=cls.loc1,
801
794
  rack_group=rack_group,
802
795
  tenant=tenant,
803
- status=cls.rack_status_map["active"],
796
+ status=cls.rack_statuses[0],
804
797
  role=rack_role,
805
798
  serial="ABCDEF",
806
799
  asset_tag="1004",
@@ -860,7 +853,7 @@ class RackReservationTestCase(FilterTestCases.FilterTestCase, FilterTestCases.Te
860
853
  self.assertEqual(self.filterset(params, self.queryset).qs.values_list("pk", flat=True)[0], value)
861
854
 
862
855
 
863
- class ManufacturerTestCase(FilterTestCases.NameSlugFilterTestCase):
856
+ class ManufacturerTestCase(FilterTestCases.NameOnlyFilterTestCase):
864
857
  queryset = Manufacturer.objects.all()
865
858
  filterset = ManufacturerFilterSet
866
859
  generic_filter_tests = [
@@ -870,7 +863,7 @@ class ManufacturerTestCase(FilterTestCases.NameSlugFilterTestCase):
870
863
  ("inventory_items", "inventory_items__id"),
871
864
  ("inventory_items", "inventory_items__name"),
872
865
  ("platforms", "platforms__id"),
873
- ("platforms", "platforms__slug"),
866
+ ("platforms", "platforms__name"),
874
867
  ]
875
868
 
876
869
  @classmethod
@@ -901,7 +894,7 @@ class DeviceTypeTestCase(FilterTestCases.FilterTestCase):
901
894
  ("interface_templates", "interface_templates__id"),
902
895
  ("interface_templates", "interface_templates__name"),
903
896
  ("manufacturer", "manufacturer__id"),
904
- ("manufacturer", "manufacturer__slug"),
897
+ ("manufacturer", "manufacturer__name"),
905
898
  ("model",),
906
899
  ("part_number",),
907
900
  ("power_outlet_templates", "power_outlet_templates__id"),
@@ -910,7 +903,6 @@ class DeviceTypeTestCase(FilterTestCases.FilterTestCase):
910
903
  ("power_port_templates", "power_port_templates__name"),
911
904
  ("rear_port_templates", "rear_port_templates__id"),
912
905
  ("rear_port_templates", "rear_port_templates__name"),
913
- ("slug",),
914
906
  ("u_height",),
915
907
  ]
916
908
 
@@ -919,7 +911,7 @@ class DeviceTypeTestCase(FilterTestCases.FilterTestCase):
919
911
  common_test_data(cls)
920
912
 
921
913
  manufacturer = Manufacturer.objects.first()
922
- DeviceType.objects.create(
914
+ device_type = DeviceType.objects.create(
923
915
  manufacturer=manufacturer,
924
916
  comments="Device type 4",
925
917
  model="Model 4",
@@ -928,6 +920,7 @@ class DeviceTypeTestCase(FilterTestCases.FilterTestCase):
928
920
  u_height=4,
929
921
  is_full_depth=True,
930
922
  )
923
+ device_type.tags.set(Tag.objects.get_for_model(DeviceType))
931
924
 
932
925
  def test_is_full_depth(self):
933
926
  # TODO: Not a generic_filter_test because this is a boolean filter but not a RelatedMembershipBooleanFilter
@@ -1240,14 +1233,14 @@ class DeviceBayTemplateTestCase(Mixins.ComponentTemplateMixin):
1240
1233
  filterset = DeviceBayTemplateFilterSet
1241
1234
 
1242
1235
 
1243
- class PlatformTestCase(FilterTestCases.NameSlugFilterTestCase):
1236
+ class PlatformTestCase(FilterTestCases.NameOnlyFilterTestCase):
1244
1237
  queryset = Platform.objects.all()
1245
1238
  filterset = PlatformFilterSet
1246
1239
  generic_filter_tests = [
1247
1240
  ("description",),
1248
1241
  ("devices", "devices__id"),
1249
1242
  ("manufacturer", "manufacturer__id"),
1250
- ("manufacturer", "manufacturer__slug"),
1243
+ ("manufacturer", "manufacturer__name"),
1251
1244
  ("napalm_driver",),
1252
1245
  ("virtual_machines", "virtual_machines__id"),
1253
1246
  ]
@@ -1277,7 +1270,7 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
1277
1270
  ("console_server_ports", "console_server_ports__id"),
1278
1271
  ("device_bays", "device_bays__id"),
1279
1272
  ("device_redundancy_group", "device_redundancy_group__id"),
1280
- ("device_redundancy_group", "device_redundancy_group__slug"),
1273
+ ("device_redundancy_group", "device_redundancy_group__name"),
1281
1274
  ("device_redundancy_group_priority",),
1282
1275
  ("device_type", "device_type__id"),
1283
1276
  ("device_type", "device_type__slug"),
@@ -1285,10 +1278,10 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
1285
1278
  ("interfaces", "interfaces__id"),
1286
1279
  ("mac_address", "interfaces__mac_address"),
1287
1280
  ("manufacturer", "device_type__manufacturer__id"),
1288
- ("manufacturer", "device_type__manufacturer__slug"),
1281
+ ("manufacturer", "device_type__manufacturer__name"),
1289
1282
  ("name",),
1290
1283
  ("platform", "platform__id"),
1291
- ("platform", "platform__slug"),
1284
+ ("platform", "platform__name"),
1292
1285
  ("position",),
1293
1286
  ("power_outlets", "power_outlets__id"),
1294
1287
  ("power_ports", "power_ports__id"),
@@ -1298,10 +1291,10 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
1298
1291
  ("rack_group", "rack__rack_group__slug"),
1299
1292
  ("rear_ports", "rear_ports__id"),
1300
1293
  ("role", "role__id"),
1301
- ("role", "role__slug"),
1294
+ ("role", "role__name"),
1302
1295
  ("secrets_group", "secrets_group__id"),
1303
- ("secrets_group", "secrets_group__slug"),
1304
- ("status", "status__slug"),
1296
+ ("secrets_group", "secrets_group__name"),
1297
+ ("status", "status__name"),
1305
1298
  ("vc_position",),
1306
1299
  ("vc_priority",),
1307
1300
  ("virtual_chassis", "virtual_chassis__id"),
@@ -1351,11 +1344,16 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
1351
1344
 
1352
1345
  # Assign primary IPs for filtering
1353
1346
  interfaces = Interface.objects.all()
1347
+ ipaddr_status = Status.objects.get_for_model(IPAddress).first()
1348
+ prefix_status = Status.objects.get_for_model(Prefix).first()
1349
+ namespace = Namespace.objects.first()
1350
+ Prefix.objects.create(prefix="192.0.2.0/24", namespace=namespace, status=prefix_status)
1351
+ Prefix.objects.create(prefix="2600::/64", namespace=namespace, status=prefix_status)
1354
1352
  ipaddresses = (
1355
- IPAddress.objects.create(address="192.0.2.1/24"),
1356
- IPAddress.objects.create(address="192.0.2.2/24"),
1357
- IPAddress.objects.create(address="2600::1/120"),
1358
- IPAddress.objects.create(address="2600::0100/120"),
1353
+ IPAddress.objects.create(address="192.0.2.1/24", namespace=namespace, status=ipaddr_status),
1354
+ IPAddress.objects.create(address="192.0.2.2/24", namespace=namespace, status=ipaddr_status),
1355
+ IPAddress.objects.create(address="2600::1/120", namespace=namespace, status=ipaddr_status),
1356
+ IPAddress.objects.create(address="2600::0100/120", namespace=namespace, status=ipaddr_status),
1359
1357
  )
1360
1358
 
1361
1359
  interfaces[0].add_ip_addresses([ipaddresses[0], ipaddresses[2]])
@@ -1516,7 +1514,7 @@ class ConsolePortTestCase(FilterTestCases.FilterTestCase):
1516
1514
  console_ports[0].tags.set(Tag.objects.get_for_model(ConsolePort))
1517
1515
 
1518
1516
  cable_statuses = Status.objects.get_for_model(Cable)
1519
- status_connected = cable_statuses.get(slug="connected")
1517
+ status_connected = cable_statuses.get(name="Connected")
1520
1518
 
1521
1519
  # Cables
1522
1520
  Cable.objects.create(
@@ -1575,7 +1573,7 @@ class ConsoleServerPortTestCase(FilterTestCases.FilterTestCase):
1575
1573
  console_server_ports[0].tags.set(Tag.objects.get_for_model(ConsoleServerPort))
1576
1574
 
1577
1575
  cable_statuses = Status.objects.get_for_model(Cable)
1578
- status_connected = cable_statuses.get(slug="connected")
1576
+ status_connected = cable_statuses.get(name="Connected")
1579
1577
 
1580
1578
  # Cables
1581
1579
  Cable.objects.create(
@@ -1640,7 +1638,7 @@ class PowerPortTestCase(FilterTestCases.FilterTestCase):
1640
1638
  power_ports[1].tags.set(Tag.objects.get_for_model(PowerPort)[:3])
1641
1639
 
1642
1640
  cable_statuses = Status.objects.get_for_model(Cable)
1643
- status_connected = cable_statuses.get(slug="connected")
1641
+ status_connected = cable_statuses.get(name="Connected")
1644
1642
 
1645
1643
  # Cables
1646
1644
  Cable.objects.create(
@@ -1701,7 +1699,7 @@ class PowerOutletTestCase(FilterTestCases.FilterTestCase):
1701
1699
  )
1702
1700
 
1703
1701
  cable_statuses = Status.objects.get_for_model(Cable)
1704
- status_connected = cable_statuses.get(slug="connected")
1702
+ status_connected = cable_statuses.get(name="Connected")
1705
1703
 
1706
1704
  # Cables
1707
1705
  Cable.objects.create(
@@ -1756,7 +1754,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1756
1754
  ("name",),
1757
1755
  ("parent_interface", "parent_interface__id"),
1758
1756
  ("parent_interface", "parent_interface__name"),
1759
- ("status", "status__slug"),
1757
+ ("status", "status__name"),
1760
1758
  ("type",),
1761
1759
  ("tagged_vlans", "tagged_vlans__id"),
1762
1760
  ("tagged_vlans", "tagged_vlans__vid"),
@@ -1776,7 +1774,6 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1776
1774
  vlans = VLAN.objects.all()[:3]
1777
1775
 
1778
1776
  interface_statuses = Status.objects.get_for_model(Interface)
1779
- interface_status_map = {s.slug: s for s in interface_statuses.all()}
1780
1777
 
1781
1778
  # Cabled interfaces
1782
1779
  cabled_interfaces = (
@@ -1790,7 +1787,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1790
1787
  mode=InterfaceModeChoices.MODE_TAGGED,
1791
1788
  enabled=True,
1792
1789
  mgmt_only=True,
1793
- status=interface_status_map["failed"],
1790
+ status=interface_statuses[2],
1794
1791
  untagged_vlan=vlans[2],
1795
1792
  ),
1796
1793
  Interface.objects.create(
@@ -1800,7 +1797,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1800
1797
  mode=InterfaceModeChoices.MODE_TAGGED,
1801
1798
  enabled=True,
1802
1799
  mgmt_only=True,
1803
- status=interface_status_map["planned"],
1800
+ status=interface_statuses[3],
1804
1801
  ),
1805
1802
  Interface.objects.create(
1806
1803
  device=devices[2],
@@ -1809,7 +1806,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1809
1806
  mode=InterfaceModeChoices.MODE_TAGGED,
1810
1807
  enabled=False,
1811
1808
  mgmt_only=True,
1812
- status=interface_status_map["active"],
1809
+ status=interface_statuses[0],
1813
1810
  ),
1814
1811
  )
1815
1812
  interface_taggable_vlan_1 = VLAN.objects.filter(location=devices[2].location).first()
@@ -1826,7 +1823,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1826
1823
  mac_address="00-00-00-00-00-01",
1827
1824
  mode=InterfaceModeChoices.MODE_ACCESS,
1828
1825
  mtu=100,
1829
- status=interface_status_map["active"],
1826
+ status=interface_statuses[0],
1830
1827
  untagged_vlan=vlans[0],
1831
1828
  )
1832
1829
 
@@ -1835,7 +1832,7 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1835
1832
  mac_address="00-00-00-00-00-02",
1836
1833
  mode=InterfaceModeChoices.MODE_TAGGED,
1837
1834
  mtu=200,
1838
- status=interface_status_map["planned"],
1835
+ status=interface_statuses[3],
1839
1836
  untagged_vlan=vlans[1],
1840
1837
  )
1841
1838
 
@@ -1844,25 +1841,25 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1844
1841
  mac_address="00-00-00-00-00-03",
1845
1842
  mode=InterfaceModeChoices.MODE_TAGGED_ALL,
1846
1843
  mtu=300,
1847
- status=interface_status_map["failed"],
1844
+ status=interface_statuses[2],
1848
1845
  )
1849
1846
 
1850
1847
  for interface in cabled_interfaces:
1851
1848
  interface.refresh_from_db()
1852
1849
 
1853
1850
  cable_statuses = Status.objects.get_for_model(Cable)
1854
- cable_status_map = {cs.slug: cs for cs in cable_statuses.all()}
1851
+ connected_status = cable_statuses.get(name="Connected")
1855
1852
 
1856
1853
  # Cables
1857
1854
  Cable.objects.create(
1858
1855
  termination_a=cabled_interfaces[0],
1859
1856
  termination_b=cabled_interfaces[3],
1860
- status=cable_status_map["connected"],
1857
+ status=connected_status,
1861
1858
  )
1862
1859
  Cable.objects.create(
1863
1860
  termination_a=cabled_interfaces[1],
1864
1861
  termination_b=cabled_interfaces[4],
1865
- status=cable_status_map["connected"],
1862
+ status=connected_status,
1866
1863
  )
1867
1864
  # Third pair is not connected
1868
1865
 
@@ -1871,21 +1868,21 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1871
1868
  device=cabled_interfaces[3].device,
1872
1869
  name="Child 1",
1873
1870
  parent_interface=cabled_interfaces[3],
1874
- status=interface_status_map["planned"],
1871
+ status=interface_statuses[3],
1875
1872
  type=InterfaceTypeChoices.TYPE_VIRTUAL,
1876
1873
  )
1877
1874
  Interface.objects.create(
1878
1875
  device=cabled_interfaces[4].device,
1879
1876
  name="Child 2",
1880
1877
  parent_interface=cabled_interfaces[4],
1881
- status=interface_status_map["planned"],
1878
+ status=interface_statuses[3],
1882
1879
  type=InterfaceTypeChoices.TYPE_VIRTUAL,
1883
1880
  )
1884
1881
  Interface.objects.create(
1885
1882
  device=cabled_interfaces[5].device,
1886
1883
  name="Child 3",
1887
1884
  parent_interface=cabled_interfaces[5],
1888
- status=interface_status_map["planned"],
1885
+ status=interface_statuses[3],
1889
1886
  type=InterfaceTypeChoices.TYPE_VIRTUAL,
1890
1887
  )
1891
1888
 
@@ -1894,19 +1891,19 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1894
1891
  Interface.objects.create(
1895
1892
  device=devices[2],
1896
1893
  name="Bridge 1",
1897
- status=interface_status_map["planned"],
1894
+ status=interface_statuses[3],
1898
1895
  type=InterfaceTypeChoices.TYPE_BRIDGE,
1899
1896
  ),
1900
1897
  Interface.objects.create(
1901
1898
  device=devices[2],
1902
1899
  name="Bridge 2",
1903
- status=interface_status_map["planned"],
1900
+ status=interface_statuses[3],
1904
1901
  type=InterfaceTypeChoices.TYPE_BRIDGE,
1905
1902
  ),
1906
1903
  Interface.objects.create(
1907
1904
  device=devices[2],
1908
1905
  name="Bridge 3",
1909
- status=interface_status_map["planned"],
1906
+ status=interface_statuses[3],
1910
1907
  type=InterfaceTypeChoices.TYPE_BRIDGE,
1911
1908
  ),
1912
1909
  )
@@ -1914,21 +1911,21 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1914
1911
  device=bridge_interfaces[0].device,
1915
1912
  name="Bridged 1",
1916
1913
  bridge=bridge_interfaces[0],
1917
- status=interface_status_map["planned"],
1914
+ status=interface_statuses[3],
1918
1915
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1919
1916
  )
1920
1917
  Interface.objects.create(
1921
1918
  device=bridge_interfaces[1].device,
1922
1919
  name="Bridged 2",
1923
1920
  bridge=bridge_interfaces[1],
1924
- status=interface_status_map["planned"],
1921
+ status=interface_statuses[3],
1925
1922
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1926
1923
  )
1927
1924
  Interface.objects.create(
1928
1925
  device=bridge_interfaces[2].device,
1929
1926
  name="Bridged 3",
1930
1927
  bridge=bridge_interfaces[2],
1931
- status=interface_status_map["planned"],
1928
+ status=interface_statuses[3],
1932
1929
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1933
1930
  )
1934
1931
 
@@ -1938,19 +1935,19 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1938
1935
  device=devices[2],
1939
1936
  name="LAG 1",
1940
1937
  type=InterfaceTypeChoices.TYPE_LAG,
1941
- status=interface_status_map["planned"],
1938
+ status=interface_statuses[3],
1942
1939
  ),
1943
1940
  Interface.objects.create(
1944
1941
  device=devices[2],
1945
1942
  name="LAG 2",
1946
1943
  type=InterfaceTypeChoices.TYPE_LAG,
1947
- status=interface_status_map["planned"],
1944
+ status=interface_statuses[3],
1948
1945
  ),
1949
1946
  Interface.objects.create(
1950
1947
  device=devices[2],
1951
1948
  name="LAG 3",
1952
1949
  type=InterfaceTypeChoices.TYPE_LAG,
1953
- status=interface_status_map["planned"],
1950
+ status=interface_statuses[3],
1954
1951
  ),
1955
1952
  )
1956
1953
  Interface.objects.create(
@@ -1958,21 +1955,21 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
1958
1955
  name="Member 1",
1959
1956
  lag=lag_interfaces[0],
1960
1957
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1961
- status=interface_status_map["planned"],
1958
+ status=interface_statuses[3],
1962
1959
  )
1963
1960
  Interface.objects.create(
1964
1961
  device=devices[2],
1965
1962
  name="Member 2",
1966
1963
  lag=lag_interfaces[1],
1967
1964
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1968
- status=interface_status_map["planned"],
1965
+ status=interface_statuses[3],
1969
1966
  )
1970
1967
  Interface.objects.create(
1971
1968
  device=devices[2],
1972
1969
  name="Member 3",
1973
1970
  lag=lag_interfaces[2],
1974
1971
  type=InterfaceTypeChoices.TYPE_1GE_SFP,
1975
- status=interface_status_map["planned"],
1972
+ status=interface_statuses[3],
1976
1973
  )
1977
1974
 
1978
1975
  def test_connected(self):
@@ -2011,23 +2008,27 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
2011
2008
  """Assert only interfaces belonging to devices with common VC are returned"""
2012
2009
  device_type = DeviceType.objects.first()
2013
2010
  device_role = Role.objects.get_for_model(Device).first()
2011
+ device_status = Status.objects.get_for_model(Device).first()
2014
2012
  devices = (
2015
2013
  Device.objects.create(
2016
2014
  name="Device in vc 1",
2017
2015
  device_type=device_type,
2018
2016
  role=device_role,
2017
+ status=device_status,
2019
2018
  location=self.loc1,
2020
2019
  ),
2021
2020
  Device.objects.create(
2022
2021
  name="Device in vc 2",
2023
2022
  device_type=device_type,
2024
2023
  role=device_role,
2024
+ status=device_status,
2025
2025
  location=self.loc1,
2026
2026
  ),
2027
2027
  Device.objects.create(
2028
2028
  name="Device not in vc",
2029
2029
  device_type=device_type,
2030
2030
  role=device_role,
2031
+ status=device_status,
2031
2032
  location=self.loc1,
2032
2033
  ),
2033
2034
  )
@@ -2037,10 +2038,11 @@ class InterfaceTestCase(FilterTestCases.FilterTestCase):
2037
2038
  Device.objects.filter(pk=devices[0].pk).update(virtual_chassis=virtual_chassis, vc_position=1, vc_priority=1)
2038
2039
  Device.objects.filter(pk=devices[1].pk).update(virtual_chassis=virtual_chassis, vc_position=2, vc_priority=2)
2039
2040
 
2040
- Interface.objects.create(device=devices[0], name="int1")
2041
- Interface.objects.create(device=devices[0], name="int2")
2042
- Interface.objects.create(device=devices[1], name="int3")
2043
- Interface.objects.create(device=devices[2], name="int4")
2041
+ interface_status = Status.objects.get_for_model(Interface).first()
2042
+ Interface.objects.create(device=devices[0], name="int1", status=interface_status)
2043
+ Interface.objects.create(device=devices[0], name="int2", status=interface_status)
2044
+ Interface.objects.create(device=devices[1], name="int3", status=interface_status)
2045
+ Interface.objects.create(device=devices[2], name="int4", status=interface_status)
2044
2046
 
2045
2047
  params = {"device_with_common_vc": devices[0].pk}
2046
2048
  queryset = self.filterset(params, self.queryset).qs
@@ -2159,7 +2161,7 @@ class FrontPortTestCase(FilterTestCases.FilterTestCase):
2159
2161
  front_ports[1].tags.set(Tag.objects.get_for_model(FrontPort)[:3])
2160
2162
 
2161
2163
  cable_statuses = Status.objects.get_for_model(Cable)
2162
- status_connected = cable_statuses.get(slug="connected")
2164
+ status_connected = cable_statuses.get(name="Connected")
2163
2165
 
2164
2166
  # Cables
2165
2167
  Cable.objects.create(
@@ -2226,7 +2228,7 @@ class RearPortTestCase(FilterTestCases.FilterTestCase):
2226
2228
  rear_ports[1].tags.set(Tag.objects.get_for_model(RearPort)[:3])
2227
2229
 
2228
2230
  cable_statuses = Status.objects.get_for_model(Cable)
2229
- status_connected = cable_statuses.get(slug="connected")
2231
+ status_connected = cable_statuses.get(name="Connected")
2230
2232
 
2231
2233
  # Cables
2232
2234
  Cable.objects.create(
@@ -2269,7 +2271,6 @@ class DeviceBayTestCase(FilterTestCases.FilterTestCase):
2269
2271
  child_device_type = DeviceType.objects.get(slug="model-3")
2270
2272
 
2271
2273
  device_statuses = Status.objects.get_for_model(Device)
2272
- device_status_map = {ds.slug: ds for ds in device_statuses.all()}
2273
2274
 
2274
2275
  child_devices = (
2275
2276
  Device.objects.create(
@@ -2277,14 +2278,14 @@ class DeviceBayTestCase(FilterTestCases.FilterTestCase):
2277
2278
  device_type=child_device_type,
2278
2279
  role=device_role,
2279
2280
  location=cls.loc1,
2280
- status=device_status_map["active"],
2281
+ status=device_statuses[0],
2281
2282
  ),
2282
2283
  Device.objects.create(
2283
2284
  name="Child Device 2",
2284
2285
  device_type=child_device_type,
2285
2286
  role=device_role,
2286
2287
  location=cls.loc1,
2287
- status=device_status_map["active"],
2288
+ status=device_statuses[0],
2288
2289
  ),
2289
2290
  )
2290
2291
 
@@ -2294,14 +2295,14 @@ class DeviceBayTestCase(FilterTestCases.FilterTestCase):
2294
2295
  device_type=parent_device_type,
2295
2296
  role=device_role,
2296
2297
  location=cls.loc1,
2297
- status=device_status_map["active"],
2298
+ status=device_statuses[0],
2298
2299
  ),
2299
2300
  Device.objects.create(
2300
2301
  name="Parent Device 2",
2301
2302
  device_type=parent_device_type,
2302
2303
  role=device_role,
2303
2304
  location=cls.loc1,
2304
- status=device_status_map["active"],
2305
+ status=device_statuses[0],
2305
2306
  ),
2306
2307
  )
2307
2308
 
@@ -2327,7 +2328,7 @@ class InventoryItemTestCase(FilterTestCases.FilterTestCase):
2327
2328
  ("device", "device__name"),
2328
2329
  ("label",),
2329
2330
  ("manufacturer", "manufacturer__id"),
2330
- ("manufacturer", "manufacturer__slug"),
2331
+ ("manufacturer", "manufacturer__name"),
2331
2332
  ("name",),
2332
2333
  ("parent", "parent__id"),
2333
2334
  ("parent", "parent__name"),
@@ -2425,10 +2426,10 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2425
2426
 
2426
2427
  @classmethod
2427
2428
  def setUpTestData(cls):
2428
-
2429
- manufacturer = Manufacturer.objects.create(name="Manufacturer 1", slug="manufacturer-1")
2429
+ manufacturer = Manufacturer.objects.first()
2430
2430
  device_type = DeviceType.objects.create(manufacturer=manufacturer, model="Model 1", slug="model-1")
2431
2431
  device_role = Role.objects.get_for_model(Device).first()
2432
+ device_status = Status.objects.get_for_model(Device).first()
2432
2433
 
2433
2434
  cls.locations = Location.objects.filter(location_type=LocationType.objects.get(name="Campus"))[:3]
2434
2435
  devices = (
@@ -2438,6 +2439,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2438
2439
  role=device_role,
2439
2440
  location=cls.locations[0],
2440
2441
  vc_position=1,
2442
+ status=device_status,
2441
2443
  ),
2442
2444
  Device.objects.create(
2443
2445
  name="Device 2",
@@ -2445,6 +2447,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2445
2447
  role=device_role,
2446
2448
  location=cls.locations[0],
2447
2449
  vc_position=2,
2450
+ status=device_status,
2448
2451
  ),
2449
2452
  Device.objects.create(
2450
2453
  name="Device 3",
@@ -2452,6 +2455,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2452
2455
  role=device_role,
2453
2456
  location=cls.locations[1],
2454
2457
  vc_position=1,
2458
+ status=device_status,
2455
2459
  ),
2456
2460
  Device.objects.create(
2457
2461
  name="Device 4",
@@ -2459,6 +2463,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2459
2463
  role=device_role,
2460
2464
  location=cls.locations[1],
2461
2465
  vc_position=2,
2466
+ status=device_status,
2462
2467
  ),
2463
2468
  Device.objects.create(
2464
2469
  name="Device 5",
@@ -2466,6 +2471,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2466
2471
  role=device_role,
2467
2472
  location=cls.locations[2],
2468
2473
  vc_position=1,
2474
+ status=device_status,
2469
2475
  ),
2470
2476
  Device.objects.create(
2471
2477
  name="Device 6",
@@ -2473,6 +2479,7 @@ class VirtualChassisTestCase(FilterTestCases.FilterTestCase):
2473
2479
  role=device_role,
2474
2480
  location=cls.locations[2],
2475
2481
  vc_position=2,
2482
+ status=device_status,
2476
2483
  ),
2477
2484
  )
2478
2485
 
@@ -2502,7 +2509,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2502
2509
  ("color",),
2503
2510
  ("label",),
2504
2511
  ("length",),
2505
- ("status", "status__slug"),
2512
+ ("status", "status__name"),
2506
2513
  ("termination_a_id",),
2507
2514
  ("termination_b_id",),
2508
2515
  ("type",),
@@ -2528,6 +2535,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2528
2535
  )
2529
2536
 
2530
2537
  device_role = Role.objects.get_for_model(Device).first()
2538
+ device_status = Status.objects.get_for_model(Device).first()
2531
2539
 
2532
2540
  devices = (
2533
2541
  Device.objects.get(name="Device 1"),
@@ -2537,6 +2545,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2537
2545
  name="Device 4",
2538
2546
  device_type=device_types[0],
2539
2547
  role=device_role,
2548
+ status=device_status,
2540
2549
  tenant=tenants[0],
2541
2550
  location=cls.locations[0],
2542
2551
  rack=racks[0],
@@ -2546,6 +2555,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2546
2555
  name="Device 5",
2547
2556
  device_type=device_types[1],
2548
2557
  role=device_role,
2558
+ status=device_status,
2549
2559
  tenant=tenants[1],
2550
2560
  location=cls.locations[1],
2551
2561
  rack=racks[1],
@@ -2555,6 +2565,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2555
2565
  name="Device 6",
2556
2566
  device_type=device_types[2],
2557
2567
  role=device_role,
2568
+ status=device_status,
2558
2569
  tenant=tenants[2],
2559
2570
  location=cls.locations[2],
2560
2571
  rack=racks[2],
@@ -2562,6 +2573,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2562
2573
  ),
2563
2574
  )
2564
2575
 
2576
+ interface_status = Status.objects.get_for_model(Interface).first()
2565
2577
  interfaces = (
2566
2578
  Interface.objects.get(device__name="Device 1"),
2567
2579
  Interface.objects.get(device__name="Device 2"),
@@ -2573,38 +2585,44 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2573
2585
  device=devices[0],
2574
2586
  name="Interface 7",
2575
2587
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2588
+ status=interface_status,
2576
2589
  ),
2577
2590
  Interface.objects.create(
2578
2591
  device=devices[1],
2579
2592
  name="Interface 8",
2580
2593
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2594
+ status=interface_status,
2581
2595
  ),
2582
2596
  Interface.objects.create(
2583
2597
  device=devices[2],
2584
2598
  name="Interface 9",
2585
2599
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2600
+ status=interface_status,
2586
2601
  ),
2587
2602
  Interface.objects.create(
2588
2603
  device=devices[3],
2589
2604
  name="Interface 10",
2590
2605
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2606
+ status=interface_status,
2591
2607
  ),
2592
2608
  Interface.objects.create(
2593
2609
  device=devices[4],
2594
2610
  name="Interface 11",
2595
2611
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2612
+ status=interface_status,
2596
2613
  ),
2597
2614
  Interface.objects.create(
2598
2615
  device=devices[5],
2599
2616
  name="Interface 12",
2600
2617
  type=InterfaceTypeChoices.TYPE_1GE_FIXED,
2618
+ status=interface_status,
2601
2619
  ),
2602
2620
  )
2603
2621
 
2604
2622
  statuses = Status.objects.get_for_model(Cable)
2605
- cls.status_connected = statuses.get(slug="connected")
2606
- cls.status_decommissioning = statuses.get(slug="decommissioning")
2607
- cls.status_planned = statuses.get(slug="planned")
2623
+ cls.status_connected = statuses.get(name="Connected")
2624
+ cls.status_decommissioning = statuses.get(name="Decommissioning")
2625
+ cls.status_planned = statuses.get(name="Planned")
2608
2626
 
2609
2627
  console_port = ConsolePort.objects.filter(device=devices[2]).first()
2610
2628
  console_server_port = ConsoleServerPort.objects.filter(device=devices[5]).first()
@@ -2715,7 +2733,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2715
2733
  ),
2716
2734
  )
2717
2735
  with self.subTest():
2718
- params = {"tenant": [tenants[0].slug, tenants[1].slug]}
2736
+ params = {"tenant": [tenants[0].name, tenants[1].name]}
2719
2737
  self.assertQuerysetEqual(
2720
2738
  self.filterset(params, self.queryset).qs,
2721
2739
  self.queryset.filter(
@@ -2741,6 +2759,12 @@ class CableTestCase(FilterTestCases.FilterTestCase):
2741
2759
  with self.subTest():
2742
2760
  params = {"termination_b_type": [type_interface]}
2743
2761
  self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)
2762
+ with self.subTest():
2763
+ params = {"termination_type": [type_interface]}
2764
+ self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5)
2765
+ with self.subTest():
2766
+ params = {"termination_type": [type_console_port, type_console_server_port]}
2767
+ self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
2744
2768
 
2745
2769
 
2746
2770
  class PowerPanelTestCase(FilterTestCases.FilterTestCase):
@@ -2775,7 +2799,7 @@ class PowerFeedTestCase(FilterTestCases.FilterTestCase):
2775
2799
  ("power_panel", "power_panel__name"),
2776
2800
  ("rack", "rack__id"),
2777
2801
  ("rack", "rack__name"),
2778
- ("status", "status__slug"),
2802
+ ("status", "status__name"),
2779
2803
  ("voltage",),
2780
2804
  ]
2781
2805
 
@@ -2790,10 +2814,9 @@ class PowerFeedTestCase(FilterTestCases.FilterTestCase):
2790
2814
  )
2791
2815
 
2792
2816
  pf_statuses = Status.objects.get_for_model(PowerFeed)
2793
- pf_status_map = {s.slug: s for s in pf_statuses.all()}
2794
2817
 
2795
2818
  PowerFeed.objects.filter(pk=power_feeds[0].pk).update(
2796
- status=pf_status_map["active"],
2819
+ status=pf_statuses[0],
2797
2820
  type=PowerFeedTypeChoices.TYPE_PRIMARY,
2798
2821
  supply=PowerFeedSupplyChoices.SUPPLY_AC,
2799
2822
  phase=PowerFeedPhaseChoices.PHASE_3PHASE,
@@ -2803,7 +2826,7 @@ class PowerFeedTestCase(FilterTestCases.FilterTestCase):
2803
2826
  comments="PFA",
2804
2827
  )
2805
2828
  PowerFeed.objects.filter(pk=power_feeds[1].pk).update(
2806
- status=pf_status_map["failed"],
2829
+ status=pf_statuses[1],
2807
2830
  type=PowerFeedTypeChoices.TYPE_PRIMARY,
2808
2831
  supply=PowerFeedSupplyChoices.SUPPLY_AC,
2809
2832
  phase=PowerFeedPhaseChoices.PHASE_3PHASE,
@@ -2813,7 +2836,7 @@ class PowerFeedTestCase(FilterTestCases.FilterTestCase):
2813
2836
  comments="PFB",
2814
2837
  )
2815
2838
  PowerFeed.objects.filter(pk=power_feeds[2].pk).update(
2816
- status=pf_status_map["offline"],
2839
+ status=pf_statuses[2],
2817
2840
  type=PowerFeedTypeChoices.TYPE_REDUNDANT,
2818
2841
  supply=PowerFeedSupplyChoices.SUPPLY_DC,
2819
2842
  phase=PowerFeedPhaseChoices.PHASE_SINGLE,
@@ -2836,7 +2859,7 @@ class PowerFeedTestCase(FilterTestCases.FilterTestCase):
2836
2859
  )
2837
2860
 
2838
2861
  cable_statuses = Status.objects.get_for_model(Cable)
2839
- status_connected = cable_statuses.get(slug="connected")
2862
+ status_connected = cable_statuses.get(name="Connected")
2840
2863
 
2841
2864
  Cable.objects.create(
2842
2865
  termination_a=power_feeds[0],
@@ -2880,8 +2903,7 @@ class DeviceRedundancyGroupTestCase(FilterTestCases.FilterTestCase):
2880
2903
  generic_filter_tests = [
2881
2904
  ("name",),
2882
2905
  ("secrets_group", "secrets_group__id"),
2883
- ("secrets_group", "secrets_group__slug"),
2884
- ("slug",),
2906
+ ("secrets_group", "secrets_group__name"),
2885
2907
  ]
2886
2908
 
2887
2909
  @classmethod