nautobot 2.4.0b1__py3-none-any.whl → 2.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of nautobot might be problematic. Click here for more details.

Files changed (668) hide show
  1. nautobot/apps/__init__.py +1 -1
  2. nautobot/apps/api.py +8 -8
  3. nautobot/apps/change_logging.py +2 -2
  4. nautobot/apps/choices.py +4 -4
  5. nautobot/apps/events.py +3 -3
  6. nautobot/apps/factory.py +2 -2
  7. nautobot/apps/filters.py +1 -1
  8. nautobot/apps/forms.py +20 -20
  9. nautobot/apps/graphql.py +2 -2
  10. nautobot/apps/jobs.py +8 -8
  11. nautobot/apps/models.py +19 -19
  12. nautobot/apps/tables.py +1 -1
  13. nautobot/apps/testing.py +10 -10
  14. nautobot/apps/ui.py +2 -2
  15. nautobot/apps/utils.py +7 -7
  16. nautobot/apps/views.py +7 -7
  17. nautobot/circuits/api/serializers.py +1 -0
  18. nautobot/circuits/api/views.py +4 -8
  19. nautobot/circuits/tables.py +2 -1
  20. nautobot/circuits/templates/circuits/circuit_create.html +1 -7
  21. nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +43 -0
  22. nautobot/circuits/tests/integration/test_relationships.py +1 -1
  23. nautobot/circuits/views.py +3 -3
  24. nautobot/cloud/api/views.py +6 -10
  25. nautobot/cloud/models.py +1 -1
  26. nautobot/cloud/views.py +0 -16
  27. nautobot/core/api/constants.py +11 -0
  28. nautobot/core/api/fields.py +5 -5
  29. nautobot/core/api/filter_backends.py +3 -9
  30. nautobot/core/api/schema.py +13 -2
  31. nautobot/core/api/serializers.py +40 -34
  32. nautobot/core/api/views.py +56 -4
  33. nautobot/core/apps/__init__.py +0 -5
  34. nautobot/core/celery/log.py +4 -4
  35. nautobot/core/celery/schedulers.py +2 -2
  36. nautobot/core/choices.py +2 -2
  37. nautobot/core/events/__init__.py +3 -3
  38. nautobot/core/filters.py +67 -35
  39. nautobot/core/forms/__init__.py +19 -19
  40. nautobot/core/forms/fields.py +14 -11
  41. nautobot/core/forms/forms.py +33 -2
  42. nautobot/core/graphql/types.py +1 -1
  43. nautobot/core/jobs/__init__.py +28 -7
  44. nautobot/core/jobs/bulk_actions.py +285 -0
  45. nautobot/core/jobs/cleanup.py +48 -12
  46. nautobot/core/jobs/groups.py +1 -1
  47. nautobot/core/management/commands/validate_models.py +1 -1
  48. nautobot/core/models/__init__.py +3 -1
  49. nautobot/core/models/query_functions.py +2 -2
  50. nautobot/core/models/tree_queries.py +6 -3
  51. nautobot/core/settings.py +29 -2
  52. nautobot/core/settings.yaml +21 -0
  53. nautobot/core/tables.py +79 -61
  54. nautobot/core/templates/about.html +67 -0
  55. nautobot/core/templates/generic/object_bulk_destroy.html +1 -1
  56. nautobot/core/templates/inc/media.html +3 -0
  57. nautobot/core/templates/inc/nav_menu.html +1 -0
  58. nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
  59. nautobot/core/templates/inc/tenant_table_row.html +11 -0
  60. nautobot/core/templates/nautobot_config.py.j2 +13 -0
  61. nautobot/core/templates/search.html +7 -0
  62. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  63. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  64. nautobot/core/templates/utilities/theme_preview.html +7 -0
  65. nautobot/core/templatetags/helpers.py +11 -2
  66. nautobot/core/testing/__init__.py +8 -8
  67. nautobot/core/testing/api.py +170 -15
  68. nautobot/core/testing/filters.py +45 -10
  69. nautobot/core/testing/forms.py +2 -0
  70. nautobot/core/testing/integration.py +514 -5
  71. nautobot/core/testing/mixins.py +7 -2
  72. nautobot/core/testing/views.py +44 -29
  73. nautobot/core/tests/integration/test_app_home.py +0 -1
  74. nautobot/core/tests/integration/test_app_navbar.py +0 -1
  75. nautobot/core/tests/integration/test_filters.py +0 -2
  76. nautobot/core/tests/integration/test_home.py +0 -1
  77. nautobot/core/tests/integration/test_navbar.py +0 -1
  78. nautobot/core/tests/integration/test_view_authentication.py +1 -0
  79. nautobot/core/tests/runner.py +1 -1
  80. nautobot/core/tests/test_api.py +98 -1
  81. nautobot/core/tests/test_csv.py +25 -3
  82. nautobot/core/tests/test_filters.py +209 -246
  83. nautobot/core/tests/test_forms.py +1 -0
  84. nautobot/core/tests/test_jobs.py +492 -1
  85. nautobot/core/tests/test_models.py +9 -0
  86. nautobot/core/tests/test_settings_schema.py +7 -0
  87. nautobot/core/tests/test_tables.py +100 -0
  88. nautobot/core/tests/test_utils.py +63 -1
  89. nautobot/core/tests/test_views.py +30 -3
  90. nautobot/core/ui/nav.py +1 -0
  91. nautobot/core/ui/object_detail.py +15 -1
  92. nautobot/core/urls.py +11 -0
  93. nautobot/core/utils/git.py +7 -2
  94. nautobot/core/utils/lookup.py +11 -8
  95. nautobot/core/utils/querysets.py +64 -0
  96. nautobot/core/utils/requests.py +24 -9
  97. nautobot/core/views/__init__.py +42 -0
  98. nautobot/core/views/generic.py +131 -197
  99. nautobot/core/views/mixins.py +136 -41
  100. nautobot/core/views/renderers.py +6 -6
  101. nautobot/core/views/utils.py +2 -2
  102. nautobot/dcim/api/serializers.py +56 -64
  103. nautobot/dcim/api/views.py +47 -113
  104. nautobot/dcim/constants.py +6 -13
  105. nautobot/dcim/factory.py +6 -1
  106. nautobot/dcim/filters/__init__.py +31 -2
  107. nautobot/dcim/forms.py +48 -17
  108. nautobot/dcim/graphql/types.py +2 -2
  109. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
  110. nautobot/dcim/models/__init__.py +1 -1
  111. nautobot/dcim/models/device_component_templates.py +2 -2
  112. nautobot/dcim/models/device_components.py +22 -20
  113. nautobot/dcim/models/devices.py +10 -1
  114. nautobot/dcim/models/locations.py +3 -3
  115. nautobot/dcim/models/power.py +6 -5
  116. nautobot/dcim/models/racks.py +4 -4
  117. nautobot/dcim/tables/__init__.py +3 -3
  118. nautobot/dcim/tables/devices.py +9 -6
  119. nautobot/dcim/tables/devicetypes.py +2 -2
  120. nautobot/dcim/tables/racks.py +1 -1
  121. nautobot/dcim/templates/dcim/cable.html +1 -1
  122. nautobot/dcim/templates/dcim/controller_create.html +1 -7
  123. nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
  124. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
  125. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
  126. nautobot/dcim/templates/dcim/device/base.html +1 -1
  127. nautobot/dcim/templates/dcim/device.html +3 -11
  128. nautobot/dcim/templates/dcim/device_component.html +1 -1
  129. nautobot/dcim/templates/dcim/device_edit.html +36 -37
  130. nautobot/dcim/templates/dcim/devicetype.html +1 -1
  131. nautobot/dcim/templates/dcim/location.html +2 -10
  132. nautobot/dcim/templates/dcim/location_edit.html +1 -7
  133. nautobot/dcim/templates/dcim/locationtype.html +1 -1
  134. nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -1
  135. nautobot/dcim/templates/dcim/manufacturer.html +1 -1
  136. nautobot/dcim/templates/dcim/platform.html +1 -1
  137. nautobot/dcim/templates/dcim/powerfeed.html +1 -1
  138. nautobot/dcim/templates/dcim/powerpanel.html +1 -1
  139. nautobot/dcim/templates/dcim/rack.html +2 -10
  140. nautobot/dcim/templates/dcim/rack_edit.html +1 -7
  141. nautobot/dcim/templates/dcim/rackgroup.html +1 -1
  142. nautobot/dcim/templates/dcim/rackreservation.html +3 -11
  143. nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
  144. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
  145. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
  146. nautobot/dcim/tests/integration/test_controller.py +62 -0
  147. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
  148. nautobot/dcim/tests/integration/test_device_bulk_operations.py +30 -0
  149. nautobot/dcim/tests/integration/test_location_bulk_operations.py +43 -0
  150. nautobot/dcim/tests/test_api.py +16 -5
  151. nautobot/dcim/tests/test_filters.py +33 -0
  152. nautobot/dcim/tests/test_forms.py +51 -2
  153. nautobot/dcim/tests/test_graphql.py +52 -0
  154. nautobot/dcim/tests/test_jobs.py +118 -0
  155. nautobot/dcim/tests/test_models.py +52 -9
  156. nautobot/dcim/tests/test_views.py +30 -84
  157. nautobot/dcim/views.py +13 -28
  158. nautobot/extras/api/customfields.py +2 -2
  159. nautobot/extras/api/serializers.py +123 -85
  160. nautobot/extras/api/views.py +33 -30
  161. nautobot/extras/constants.py +3 -0
  162. nautobot/extras/datasources/git.py +125 -0
  163. nautobot/extras/filters/__init__.py +8 -6
  164. nautobot/extras/forms/base.py +2 -2
  165. nautobot/extras/forms/forms.py +139 -31
  166. nautobot/extras/forms/mixins.py +14 -6
  167. nautobot/extras/group_sync.py +3 -3
  168. nautobot/extras/health_checks.py +1 -2
  169. nautobot/extras/jobs.py +85 -18
  170. nautobot/extras/managers.py +3 -1
  171. nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
  172. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
  173. nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
  174. nautobot/extras/migrations/0122_add_graphqlquery_owner_content_type.py +34 -0
  175. nautobot/extras/models/__init__.py +1 -1
  176. nautobot/extras/models/contacts.py +1 -1
  177. nautobot/extras/models/customfields.py +41 -23
  178. nautobot/extras/models/datasources.py +85 -0
  179. nautobot/extras/models/groups.py +11 -9
  180. nautobot/extras/models/jobs.py +23 -4
  181. nautobot/extras/models/models.py +17 -2
  182. nautobot/extras/models/relationships.py +17 -5
  183. nautobot/extras/plugins/__init__.py +13 -2
  184. nautobot/extras/plugins/marketplace_manifest.yml +84 -79
  185. nautobot/extras/plugins/tables.py +16 -14
  186. nautobot/extras/plugins/views.py +65 -69
  187. nautobot/extras/registry.py +1 -1
  188. nautobot/extras/secrets/__init__.py +2 -2
  189. nautobot/extras/signals.py +15 -1
  190. nautobot/extras/tables.py +7 -5
  191. nautobot/extras/templates/extras/computedfield.html +1 -1
  192. nautobot/extras/templates/extras/configcontext.html +1 -1
  193. nautobot/extras/templates/extras/configcontextschema.html +1 -1
  194. nautobot/extras/templates/extras/customfield.html +1 -1
  195. nautobot/extras/templates/extras/customlink.html +1 -1
  196. nautobot/extras/templates/extras/dynamicgroup.html +2 -10
  197. nautobot/extras/templates/extras/exporttemplate.html +1 -1
  198. nautobot/extras/templates/extras/gitrepository.html +1 -1
  199. nautobot/extras/templates/extras/graphqlquery.html +1 -1
  200. nautobot/extras/templates/extras/job_detail.html +17 -1
  201. nautobot/extras/templates/extras/job_edit.html +1 -0
  202. nautobot/extras/templates/extras/jobbutton_retrieve.html +1 -1
  203. nautobot/extras/templates/extras/jobhook.html +1 -1
  204. nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
  205. nautobot/extras/templates/extras/jobresult.html +1 -1
  206. nautobot/extras/templates/extras/marketplace.html +29 -11
  207. nautobot/extras/templates/extras/objectchange.html +1 -1
  208. nautobot/extras/templates/extras/plugin_detail.html +33 -16
  209. nautobot/extras/templates/extras/plugins_tiles.html +21 -10
  210. nautobot/extras/templates/extras/relationship.html +1 -63
  211. nautobot/extras/templates/extras/role_retrieve.html +1 -1
  212. nautobot/extras/templates/extras/scheduledjob.html +1 -1
  213. nautobot/extras/templates/extras/secret.html +1 -1
  214. nautobot/extras/templates/extras/secretsgroup.html +1 -1
  215. nautobot/extras/templates/extras/status.html +1 -1
  216. nautobot/extras/templates/extras/tag.html +1 -1
  217. nautobot/extras/templates/extras/webhook.html +1 -1
  218. nautobot/extras/templatetags/job_buttons.py +4 -4
  219. nautobot/extras/test_jobs/api_test_job.py +1 -1
  220. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  221. nautobot/extras/test_jobs/dry_run.py +1 -1
  222. nautobot/extras/test_jobs/fail.py +5 -5
  223. nautobot/extras/test_jobs/file_output.py +1 -1
  224. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  225. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  226. nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
  227. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  228. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  229. nautobot/extras/test_jobs/log_redaction.py +1 -1
  230. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  231. nautobot/extras/test_jobs/modify_db.py +1 -1
  232. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  233. nautobot/extras/test_jobs/object_var_required.py +1 -1
  234. nautobot/extras/test_jobs/object_vars.py +1 -1
  235. nautobot/extras/test_jobs/pass.py +3 -3
  236. nautobot/extras/test_jobs/profiling.py +1 -1
  237. nautobot/extras/test_jobs/relative_import.py +3 -3
  238. nautobot/extras/test_jobs/singleton.py +16 -0
  239. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  240. nautobot/extras/test_jobs/task_queues.py +1 -1
  241. nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_interfaces.gql +8 -0
  242. nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_names.gql +5 -0
  243. nautobot/extras/tests/git_data/02-invalid-files/graphql_queries/bad_device_names.gql +5 -0
  244. nautobot/extras/tests/git_helper.py +9 -1
  245. nautobot/extras/tests/integration/__init__.py +29 -16
  246. nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
  247. nautobot/extras/tests/test_api.py +19 -13
  248. nautobot/extras/tests/test_customfields.py +50 -52
  249. nautobot/extras/tests/test_datasources.py +29 -1
  250. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  251. nautobot/extras/tests/test_filters.py +6 -6
  252. nautobot/extras/tests/test_forms.py +33 -1
  253. nautobot/extras/tests/test_jobs.py +178 -32
  254. nautobot/extras/tests/test_models.py +299 -10
  255. nautobot/extras/tests/test_plugins.py +62 -9
  256. nautobot/extras/tests/test_relationships.py +120 -9
  257. nautobot/extras/tests/test_utils.py +22 -1
  258. nautobot/extras/tests/test_views.py +56 -194
  259. nautobot/extras/utils.py +20 -10
  260. nautobot/extras/views.py +85 -110
  261. nautobot/ipam/api/fields.py +3 -3
  262. nautobot/ipam/api/serializers.py +41 -33
  263. nautobot/ipam/api/views.py +68 -117
  264. nautobot/ipam/factory.py +1 -1
  265. nautobot/ipam/filters.py +3 -2
  266. nautobot/ipam/lookups.py +101 -62
  267. nautobot/ipam/models.py +74 -18
  268. nautobot/ipam/querysets.py +2 -2
  269. nautobot/ipam/tables.py +25 -9
  270. nautobot/ipam/templates/ipam/ipaddress.html +2 -10
  271. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
  272. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
  273. nautobot/ipam/templates/ipam/prefix.html +2 -10
  274. nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
  275. nautobot/ipam/templates/ipam/rir.html +1 -1
  276. nautobot/ipam/templates/ipam/routetarget.html +1 -1
  277. nautobot/ipam/templates/ipam/service.html +1 -1
  278. nautobot/ipam/templates/ipam/vlan.html +2 -10
  279. nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
  280. nautobot/ipam/templates/ipam/vlangroup.html +1 -1
  281. nautobot/ipam/templates/ipam/vrf.html +1 -1
  282. nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
  283. nautobot/ipam/tests/test_api.py +436 -3
  284. nautobot/ipam/tests/test_forms.py +49 -47
  285. nautobot/ipam/tests/test_migrations.py +30 -30
  286. nautobot/ipam/tests/test_models.py +119 -34
  287. nautobot/ipam/tests/test_querysets.py +63 -1
  288. nautobot/ipam/tests/test_utils.py +41 -2
  289. nautobot/ipam/tests/test_views.py +3 -0
  290. nautobot/ipam/utils/__init__.py +54 -17
  291. nautobot/ipam/views.py +61 -87
  292. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  293. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  294. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
  295. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  296. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  297. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  298. nautobot/project-static/docs/404.html +131 -14
  299. nautobot/project-static/docs/apps/index.html +131 -14
  300. nautobot/project-static/docs/apps/nautobot-apps.html +132 -16
  301. nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
  302. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.60a45f97.min.js} +2 -2
  303. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.60a45f97.min.js.map} +2 -2
  304. nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js → search.f8cc74c7.min.js} +1 -1
  305. nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js.map → search.f8cc74c7.min.js.map} +1 -1
  306. nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css → main.a40c8224.min.css} +1 -1
  307. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +147 -20
  308. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +144 -17
  309. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +459 -132
  310. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +175 -28
  311. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +180 -31
  312. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +138 -16
  313. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +137 -15
  314. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +164 -27
  315. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +187 -38
  316. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +193 -31
  317. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +216 -48
  318. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +324 -75
  319. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +666 -175
  320. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +194 -46
  321. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +538 -177
  322. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +578 -221
  323. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +145 -18
  324. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +156 -25
  325. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +492 -65
  326. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +705 -215
  327. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +943 -422
  328. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +144 -17
  329. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +619 -200
  330. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +474 -159
  331. nautobot/project-static/docs/development/apps/api/configuration-view.html +131 -14
  332. nautobot/project-static/docs/development/apps/api/database-backend-config.html +131 -14
  333. nautobot/project-static/docs/development/apps/api/models/django-admin.html +131 -14
  334. nautobot/project-static/docs/development/apps/api/models/global-search.html +131 -14
  335. nautobot/project-static/docs/development/apps/api/models/graphql.html +131 -14
  336. nautobot/project-static/docs/development/apps/api/models/index.html +131 -14
  337. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +131 -14
  338. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +131 -14
  339. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +131 -14
  340. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +131 -14
  341. nautobot/project-static/docs/development/apps/api/platform-features/index.html +131 -14
  342. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +131 -14
  343. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +131 -14
  344. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +131 -14
  345. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +131 -14
  346. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +153 -17
  347. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +131 -14
  348. nautobot/project-static/docs/development/apps/api/prometheus.html +131 -14
  349. nautobot/project-static/docs/development/apps/api/setup.html +131 -14
  350. nautobot/project-static/docs/development/apps/api/testing.html +131 -14
  351. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +131 -14
  352. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +131 -14
  353. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +131 -14
  354. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +131 -14
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +131 -14
  356. nautobot/project-static/docs/development/apps/api/views/base-template.html +131 -14
  357. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +131 -14
  358. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +131 -14
  359. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +131 -14
  360. nautobot/project-static/docs/development/apps/api/views/index.html +131 -14
  361. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +131 -14
  362. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +131 -14
  363. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +131 -14
  364. nautobot/project-static/docs/development/apps/api/views/notes.html +131 -14
  365. nautobot/project-static/docs/development/apps/api/views/rest-api.html +137 -16
  366. nautobot/project-static/docs/development/apps/api/views/urls.html +131 -14
  367. nautobot/project-static/docs/development/apps/index.html +131 -14
  368. nautobot/project-static/docs/development/apps/migration/code-updates.html +131 -14
  369. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +131 -14
  370. nautobot/project-static/docs/development/apps/migration/from-v1.html +131 -14
  371. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +131 -14
  372. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +131 -14
  373. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +131 -14
  374. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +131 -14
  375. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +135 -18
  376. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +131 -14
  377. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +297 -25
  378. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +131 -14
  379. nautobot/project-static/docs/development/apps/porting-from-netbox.html +131 -14
  380. nautobot/project-static/docs/development/core/application-registry.html +131 -14
  381. nautobot/project-static/docs/development/core/best-practices.html +131 -14
  382. nautobot/project-static/docs/development/core/bootstrap-ui.html +131 -14
  383. nautobot/project-static/docs/development/core/caching.html +131 -14
  384. nautobot/project-static/docs/development/core/controllers.html +131 -14
  385. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +158 -84
  386. nautobot/project-static/docs/development/core/generic-views.html +131 -14
  387. nautobot/project-static/docs/development/core/getting-started.html +334 -234
  388. nautobot/project-static/docs/development/core/homepage.html +134 -17
  389. nautobot/project-static/docs/development/core/index.html +131 -14
  390. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9829 -0
  391. nautobot/project-static/docs/development/core/model-checklist.html +141 -22
  392. nautobot/project-static/docs/development/core/model-features.html +131 -14
  393. nautobot/project-static/docs/development/core/natural-keys.html +131 -14
  394. nautobot/project-static/docs/development/core/navigation-menu.html +131 -14
  395. nautobot/project-static/docs/development/core/release-checklist.html +134 -17
  396. nautobot/project-static/docs/development/core/role-internals.html +131 -14
  397. nautobot/project-static/docs/development/core/settings.html +131 -14
  398. nautobot/project-static/docs/development/core/style-guide.html +134 -17
  399. nautobot/project-static/docs/development/core/templates.html +132 -15
  400. nautobot/project-static/docs/development/core/testing.html +131 -14
  401. nautobot/project-static/docs/development/core/ui-component-framework.html +454 -283
  402. nautobot/project-static/docs/development/core/user-preferences.html +131 -14
  403. nautobot/project-static/docs/development/index.html +131 -14
  404. nautobot/project-static/docs/development/jobs/index.html +301 -132
  405. nautobot/project-static/docs/development/jobs/migration/from-v1.html +131 -14
  406. nautobot/project-static/docs/index.html +139 -33
  407. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  408. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  409. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  410. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  411. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  412. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  413. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  414. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  415. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  416. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  417. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  418. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  419. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  420. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  421. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  422. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  423. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  424. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  425. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  426. nautobot/project-static/docs/objects.inv +0 -0
  427. nautobot/project-static/docs/overview/application_stack.html +132 -17
  428. nautobot/project-static/docs/overview/design_philosophy.html +131 -14
  429. nautobot/project-static/docs/release-notes/index.html +137 -22
  430. nautobot/project-static/docs/release-notes/version-1.0.html +319 -203
  431. nautobot/project-static/docs/release-notes/version-1.1.html +316 -200
  432. nautobot/project-static/docs/release-notes/version-1.2.html +391 -275
  433. nautobot/project-static/docs/release-notes/version-1.3.html +417 -301
  434. nautobot/project-static/docs/release-notes/version-1.4.html +502 -387
  435. nautobot/project-static/docs/release-notes/version-1.5.html +690 -576
  436. nautobot/project-static/docs/release-notes/version-1.6.html +989 -457
  437. nautobot/project-static/docs/release-notes/version-2.0.html +613 -499
  438. nautobot/project-static/docs/release-notes/version-2.1.html +448 -334
  439. nautobot/project-static/docs/release-notes/version-2.2.html +441 -327
  440. nautobot/project-static/docs/release-notes/version-2.3.html +1171 -451
  441. nautobot/project-static/docs/release-notes/version-2.4.html +800 -111
  442. nautobot/project-static/docs/requirements.txt +2 -2
  443. nautobot/project-static/docs/search/search_index.json +1 -1
  444. nautobot/project-static/docs/sitemap.xml +303 -287
  445. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  446. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +131 -14
  447. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +131 -14
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +133 -16
  449. nautobot/project-static/docs/user-guide/administration/configuration/index.html +131 -14
  450. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +131 -14
  451. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +195 -18
  452. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +131 -14
  453. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +134 -17
  454. nautobot/project-static/docs/user-guide/administration/guides/docker.html +131 -14
  455. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +131 -14
  456. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +131 -14
  457. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +131 -14
  458. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +131 -14
  459. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +131 -14
  460. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +133 -16
  461. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +131 -14
  462. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +131 -14
  463. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +131 -14
  464. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +151 -18
  465. nautobot/project-static/docs/user-guide/administration/installation/index.html +131 -14
  466. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +132 -15
  467. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +131 -14
  468. nautobot/project-static/docs/user-guide/administration/installation/services.html +131 -14
  469. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +131 -14
  470. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +131 -14
  471. nautobot/project-static/docs/user-guide/administration/security/index.html +9420 -0
  472. nautobot/project-static/docs/user-guide/administration/security/notices.html +9843 -0
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +131 -14
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +131 -14
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +131 -14
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +131 -14
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +131 -14
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +131 -14
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +131 -14
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +134 -18
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +131 -14
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +131 -14
  483. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +131 -14
  484. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +131 -14
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +131 -14
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +131 -14
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +131 -14
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +131 -14
  489. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +131 -14
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +131 -14
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +131 -14
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +131 -14
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +131 -14
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +131 -14
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +131 -14
  496. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +131 -14
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +131 -14
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +131 -14
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +131 -14
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +131 -14
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +131 -14
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +131 -14
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +131 -14
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +131 -14
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +131 -14
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +131 -14
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +131 -14
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +131 -14
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +131 -14
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +131 -14
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +131 -14
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +131 -14
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +131 -14
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +131 -14
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +131 -14
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +131 -14
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +131 -14
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +131 -14
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +131 -14
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +131 -14
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +131 -14
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +131 -14
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +131 -14
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +131 -14
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +131 -14
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +131 -14
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +131 -14
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +131 -14
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +131 -14
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +131 -14
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +131 -14
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +131 -14
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +131 -14
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +131 -14
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +131 -14
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +131 -14
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +131 -14
  538. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +135 -22
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +131 -14
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +131 -14
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +131 -14
  542. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +131 -14
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +131 -14
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +131 -14
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +131 -14
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +131 -14
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +131 -14
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +131 -14
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +131 -14
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +131 -14
  551. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +134 -17
  552. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +131 -14
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +131 -14
  554. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +131 -14
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +131 -14
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +131 -14
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +131 -14
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +131 -14
  559. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +131 -14
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +131 -14
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +131 -14
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +131 -14
  563. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +131 -14
  564. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +131 -14
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +131 -14
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +131 -14
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +134 -17
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +131 -14
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +131 -14
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +131 -14
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +131 -14
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +131 -14
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +131 -14
  574. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +236 -34
  575. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +131 -14
  576. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +131 -14
  590. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +131 -14
  591. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +134 -17
  592. nautobot/project-static/docs/{development/core/local-k8s.html → user-guide/feature-guides/wireless-networks-and-controllers.html} +632 -566
  593. nautobot/project-static/docs/user-guide/index.html +131 -14
  594. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +131 -14
  595. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +135 -18
  596. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +131 -14
  597. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +131 -14
  598. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +131 -14
  599. nautobot/project-static/docs/user-guide/platform-functionality/events.html +131 -14
  600. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +131 -14
  601. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +131 -14
  602. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +451 -16
  603. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +131 -14
  604. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +131 -14
  605. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +131 -14
  606. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +135 -17
  607. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +131 -14
  608. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +134 -17
  609. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +131 -14
  610. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +131 -14
  611. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9797 -0
  612. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +131 -14
  613. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +131 -14
  614. nautobot/project-static/docs/user-guide/platform-functionality/note.html +131 -14
  615. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +131 -14
  616. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +132 -15
  617. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +131 -14
  618. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +131 -14
  619. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +179 -35
  620. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +159 -15
  621. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +131 -14
  622. nautobot/project-static/docs/user-guide/platform-functionality/role.html +131 -14
  623. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +131 -14
  624. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +131 -14
  625. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +131 -14
  626. nautobot/project-static/docs/user-guide/platform-functionality/status.html +131 -14
  627. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +131 -14
  628. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +131 -14
  629. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +131 -14
  630. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +131 -14
  631. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +131 -14
  632. nautobot/project-static/js/forms.js +1 -1
  633. nautobot/tenancy/api/views.py +9 -13
  634. nautobot/tenancy/templates/tenancy/tenant.html +1 -2
  635. nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
  636. nautobot/tenancy/views.py +4 -2
  637. nautobot/users/admin.py +1 -1
  638. nautobot/users/api/serializers.py +5 -4
  639. nautobot/users/api/views.py +3 -3
  640. nautobot/virtualization/api/serializers.py +4 -4
  641. nautobot/virtualization/api/views.py +5 -24
  642. nautobot/virtualization/filters.py +20 -3
  643. nautobot/virtualization/models.py +1 -1
  644. nautobot/virtualization/tables.py +2 -2
  645. nautobot/virtualization/templates/virtualization/cluster.html +1 -1
  646. nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
  647. nautobot/virtualization/templates/virtualization/clustergroup.html +1 -1
  648. nautobot/virtualization/templates/virtualization/clustertype.html +1 -1
  649. nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -10
  650. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
  651. nautobot/virtualization/templates/virtualization/vminterface.html +1 -1
  652. nautobot/virtualization/tests/test_filters.py +17 -0
  653. nautobot/wireless/filters.py +2 -2
  654. nautobot/wireless/forms.py +1 -1
  655. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
  656. nautobot/wireless/tests/integration/__init__.py +0 -0
  657. nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
  658. nautobot/wireless/tests/test_filters.py +29 -1
  659. nautobot/wireless/tests/test_views.py +22 -1
  660. nautobot/wireless/views.py +0 -10
  661. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/METADATA +9 -9
  662. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/RECORD +667 -610
  663. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/WHEEL +1 -1
  664. nautobot/core/fixtures/user-data.json +0 -59
  665. /nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css.map → main.a40c8224.min.css.map} +0 -0
  666. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/LICENSE.txt +0 -0
  667. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/NOTICE +0 -0
  668. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/entry_points.txt +0 -0
@@ -19,7 +19,6 @@ from nautobot.core.api import (
19
19
  ValidatedModelSerializer,
20
20
  )
21
21
  from nautobot.core.api.exceptions import SerializerNotFound
22
- from nautobot.core.api.fields import NautobotHyperlinkedRelatedField
23
22
  from nautobot.core.api.serializers import PolymorphicProxySerializer
24
23
  from nautobot.core.api.utils import (
25
24
  get_nested_serializer_depth,
@@ -136,12 +135,12 @@ class ConfigContextSerializer(ValidatedModelSerializer, TaggedModelSerializerMix
136
135
  owner = serializers.SerializerMethodField(read_only=True)
137
136
 
138
137
  # Conditional enablement of dynamic groups filtering
139
- def __init__(self, *args, **kwargs):
140
- super().__init__(*args, **kwargs)
141
-
138
+ @property
139
+ def fields(self):
140
+ fields = super().fields
142
141
  if not settings.CONFIG_CONTEXT_DYNAMIC_GROUPS_ENABLED:
143
- # In the case of a nested serializer, we won't have a `dynamic_groups` field at all.
144
- self.fields.pop("dynamic_groups", None)
142
+ fields.pop("dynamic_groups", None)
143
+ return fields
145
144
 
146
145
  class Meta:
147
146
  model = ConfigContext
@@ -200,10 +199,7 @@ class ConfigContextSchemaSerializer(NautobotModelSerializer):
200
199
  #
201
200
 
202
201
 
203
- class ContactSerializer(NautobotModelSerializer):
204
- # needed since this is the reverse side of the M2M field.
205
- teams = NautobotHyperlinkedRelatedField(queryset=Team.objects.all(), many=True, required=False)
206
-
202
+ class ContactSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
207
203
  class Meta:
208
204
  model = Contact
209
205
  fields = "__all__"
@@ -212,15 +208,22 @@ class ContactSerializer(NautobotModelSerializer):
212
208
  extra_kwargs = {
213
209
  "email": {"default": ""},
214
210
  "phone": {"default": ""},
211
+ "teams": {"required": False},
215
212
  }
216
213
 
217
- def validate(self, data):
218
- attrs = data.copy()
219
- attrs.pop("teams", None)
214
+ def get_field_names(self, declared_fields, info):
215
+ """Add reverse M2M for teams to the fields for this serializer."""
216
+ field_names = list(super().get_field_names(declared_fields, info))
217
+ self.extend_field_names(field_names, "teams")
218
+ return field_names
219
+
220
+ def validate(self, attrs):
221
+ local_attrs = attrs.copy()
222
+ local_attrs.pop("teams", None)
220
223
  validator = UniqueTogetherValidator(queryset=Contact.objects.all(), fields=("name", "phone", "email"))
221
- validator(attrs, self)
222
- super().validate(attrs)
223
- return data
224
+ validator(local_attrs, self)
225
+ super().validate(local_attrs)
226
+ return attrs
224
227
 
225
228
 
226
229
  class ContactAssociationSerializer(NautobotModelSerializer):
@@ -235,18 +238,18 @@ class ContactAssociationSerializer(NautobotModelSerializer):
235
238
  "team": {"required": False},
236
239
  }
237
240
 
238
- def validate(self, data):
241
+ def validate(self, attrs):
239
242
  # Validate uniqueness of (associated object, associated object type, contact/team, role)
240
243
  unique_together_fields = None
241
244
 
242
- if data.get("contact") and data.get("role"):
245
+ if attrs.get("contact") and attrs.get("role"):
243
246
  unique_together_fields = (
244
247
  "associated_object_type",
245
248
  "associated_object_id",
246
249
  "contact",
247
250
  "role",
248
251
  )
249
- elif data.get("team") and data.get("role"):
252
+ elif attrs.get("team") and attrs.get("role"):
250
253
  unique_together_fields = (
251
254
  "associated_object_type",
252
255
  "associated_object_id",
@@ -259,11 +262,11 @@ class ContactAssociationSerializer(NautobotModelSerializer):
259
262
  queryset=ContactAssociation.objects.all(),
260
263
  fields=unique_together_fields,
261
264
  )
262
- validator(data, self)
265
+ validator(attrs, self)
263
266
 
264
- super().validate(data)
267
+ super().validate(attrs)
265
268
 
266
- return data
269
+ return attrs
267
270
 
268
271
 
269
272
  #
@@ -272,6 +275,7 @@ class ContactAssociationSerializer(NautobotModelSerializer):
272
275
 
273
276
 
274
277
  class ContentTypeSerializer(BaseModelSerializer):
278
+ id = serializers.IntegerField(read_only=True)
275
279
  url = serializers.HyperlinkedIdentityField(view_name="extras-api:contenttype-detail")
276
280
  display = serializers.SerializerMethodField()
277
281
 
@@ -280,8 +284,8 @@ class ContentTypeSerializer(BaseModelSerializer):
280
284
  fields = "__all__"
281
285
 
282
286
  @extend_schema_field(serializers.CharField)
283
- def get_display(self, obj):
284
- return obj.app_labeled_name
287
+ def get_display(self, instance):
288
+ return instance.app_labeled_name
285
289
 
286
290
 
287
291
  #
@@ -433,7 +437,7 @@ class ExportTemplateSerializer(RelationshipModelSerializerMixin, ValidatedModelS
433
437
  #
434
438
 
435
439
 
436
- class ExternalIntegrationSerializer(NautobotModelSerializer):
440
+ class ExternalIntegrationSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
437
441
  class Meta:
438
442
  model = ExternalIntegration
439
443
  fields = "__all__"
@@ -455,7 +459,7 @@ class FileProxySerializer(BaseModelSerializer):
455
459
  #
456
460
 
457
461
 
458
- class GitRepositorySerializer(NautobotModelSerializer):
462
+ class GitRepositorySerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
459
463
  """Git repositories defined as a data source."""
460
464
 
461
465
  provided_contents = MultipleChoiceJSONField(
@@ -476,11 +480,32 @@ class GitRepositorySerializer(NautobotModelSerializer):
476
480
 
477
481
  class GraphQLQuerySerializer(ValidatedModelSerializer, NotesSerializerMixin):
478
482
  variables = serializers.DictField(read_only=True)
483
+ owner_content_type = ContentTypeField(
484
+ queryset=ContentType.objects.filter(FeatureQuery("graphql_query_owners").get_query()),
485
+ required=False,
486
+ allow_null=True,
487
+ default=None,
488
+ )
489
+ owner = serializers.SerializerMethodField(read_only=True)
479
490
 
480
491
  class Meta:
481
492
  model = GraphQLQuery
482
493
  fields = "__all__"
483
494
 
495
+ @extend_schema_field(
496
+ PolymorphicProxySerializer(
497
+ component_name="GraphQLQueryOwner",
498
+ resource_type_field_name="object_type",
499
+ serializers=lambda: nested_serializers_for_models(FeatureQuery("graphql_query_owners").list_subclasses()),
500
+ allow_null=True,
501
+ )
502
+ )
503
+ def get_owner(self, obj):
504
+ if obj.owner is None:
505
+ return None
506
+ depth = get_nested_serializer_depth(self)
507
+ return return_nested_serializer_data_based_on_depth(self, depth, obj, obj.owner, "owner")
508
+
484
509
 
485
510
  class GraphQLQueryInputSerializer(serializers.Serializer):
486
511
  variables = serializers.DictField(allow_null=True, default={})
@@ -502,17 +527,17 @@ class ImageAttachmentSerializer(ValidatedModelSerializer):
502
527
  model = ImageAttachment
503
528
  fields = "__all__"
504
529
 
505
- def validate(self, data):
530
+ def validate(self, attrs):
506
531
  # Validate that the parent object exists
507
532
  try:
508
- data["content_type"].get_object_for_this_type(id=data["object_id"])
533
+ attrs["content_type"].get_object_for_this_type(id=attrs["object_id"])
509
534
  except ObjectDoesNotExist:
510
- raise serializers.ValidationError(f"Invalid parent object: {data['content_type']} ID {data['object_id']}")
535
+ raise serializers.ValidationError(f"Invalid parent object: {attrs['content_type']} ID {attrs['object_id']}")
511
536
 
512
537
  # Enforce model validation
513
- super().validate(data)
538
+ super().validate(attrs)
514
539
 
515
- return data
540
+ return attrs
516
541
 
517
542
  @extend_schema_field(
518
543
  PolymorphicProxySerializer(
@@ -544,24 +569,24 @@ class JobSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
544
569
  model = Job
545
570
  fields = "__all__"
546
571
 
547
- def validate(self, data):
572
+ def validate(self, attrs):
548
573
  # note no validation for on creation of jobs because we do not support user creation of Job records via API
549
574
  if self.instance:
550
- has_sensitive_variables = data.get("has_sensitive_variables", self.instance.has_sensitive_variables)
551
- approval_required = data.get("approval_required", self.instance.approval_required)
575
+ has_sensitive_variables = attrs.get("has_sensitive_variables", self.instance.has_sensitive_variables)
576
+ approval_required = attrs.get("approval_required", self.instance.approval_required)
552
577
 
553
578
  if approval_required and has_sensitive_variables:
554
579
  error_message = "A job with sensitive variables cannot also be marked as requiring approval"
555
580
  errors = {}
556
581
 
557
- if "approval_required" in data:
582
+ if "approval_required" in attrs:
558
583
  errors["approval_required"] = [error_message]
559
- if "has_sensitive_variables" in data:
584
+ if "has_sensitive_variables" in attrs:
560
585
  errors["has_sensitive_variables"] = [error_message]
561
586
 
562
587
  raise serializers.ValidationError(errors)
563
588
 
564
- return super().validate(data)
589
+ return super().validate(attrs)
565
590
 
566
591
 
567
592
  class JobQueueSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
@@ -687,22 +712,22 @@ class JobHookSerializer(NautobotModelSerializer):
687
712
  model = JobHook
688
713
  fields = "__all__"
689
714
 
690
- def validate(self, data):
691
- validated_data = super().validate(data)
715
+ def validate(self, attrs):
716
+ validated_attrs = super().validate(attrs)
692
717
 
693
718
  conflicts = JobHook.check_for_conflicts(
694
719
  instance=self.instance,
695
- content_types=data.get("content_types"),
696
- job=data.get("job"),
697
- type_create=data.get("type_create"),
698
- type_update=data.get("type_update"),
699
- type_delete=data.get("type_delete"),
720
+ content_types=attrs.get("content_types"),
721
+ job=attrs.get("job"),
722
+ type_create=attrs.get("type_create"),
723
+ type_update=attrs.get("type_update"),
724
+ type_delete=attrs.get("type_delete"),
700
725
  )
701
726
 
702
727
  if conflicts:
703
728
  raise serializers.ValidationError(conflicts)
704
729
 
705
- return validated_data
730
+ return validated_attrs
706
731
 
707
732
 
708
733
  class JobCreationSerializer(BaseModelSerializer):
@@ -721,15 +746,15 @@ class JobCreationSerializer(BaseModelSerializer):
721
746
  model = ScheduledJob
722
747
  fields = ["url", "name", "start_time", "interval", "crontab"]
723
748
 
724
- def validate(self, data):
725
- data = super().validate(data)
749
+ def validate(self, attrs):
750
+ attrs = super().validate(attrs)
726
751
 
727
- if data["interval"] in choices.JobExecutionType.SCHEDULE_CHOICES:
728
- if "name" not in data:
752
+ if attrs["interval"] in choices.JobExecutionType.SCHEDULE_CHOICES:
753
+ if "name" not in attrs:
729
754
  raise serializers.ValidationError({"name": "Please provide a name for the job schedule."})
730
755
 
731
- if ("start_time" not in data and data["interval"] != choices.JobExecutionType.TYPE_CUSTOM) or (
732
- "start_time" in data and data["start_time"] < models.ScheduledJob.earliest_possible_time()
756
+ if ("start_time" not in attrs and attrs["interval"] != choices.JobExecutionType.TYPE_CUSTOM) or (
757
+ "start_time" in attrs and attrs["start_time"] < models.ScheduledJob.earliest_possible_time()
733
758
  ):
734
759
  raise serializers.ValidationError(
735
760
  {
@@ -737,15 +762,15 @@ class JobCreationSerializer(BaseModelSerializer):
737
762
  }
738
763
  )
739
764
 
740
- if data["interval"] == choices.JobExecutionType.TYPE_CUSTOM:
741
- if data.get("crontab") is None:
765
+ if attrs["interval"] == choices.JobExecutionType.TYPE_CUSTOM:
766
+ if attrs.get("crontab") is None:
742
767
  raise serializers.ValidationError({"crontab": "Please enter a valid crontab."})
743
768
  try:
744
- models.ScheduledJob.get_crontab(data["crontab"])
769
+ models.ScheduledJob.get_crontab(attrs["crontab"])
745
770
  except Exception as e:
746
771
  raise serializers.ValidationError({"crontab": e})
747
772
 
748
- return data
773
+ return attrs
749
774
 
750
775
 
751
776
  class JobInputSerializer(serializers.Serializer):
@@ -765,15 +790,18 @@ class JobMultiPartInputSerializer(serializers.Serializer):
765
790
  _task_queue = serializers.CharField(required=False, allow_blank=True)
766
791
  _job_queue = serializers.CharField(required=False, allow_blank=True)
767
792
 
768
- def validate(self, data):
769
- data = super().validate(data)
793
+ def validate(self, attrs):
794
+ attrs = super().validate(attrs)
770
795
 
771
- if "_schedule_interval" in data and data["_schedule_interval"] != JobExecutionType.TYPE_IMMEDIATELY:
772
- if "_schedule_name" not in data:
796
+ if "_schedule_interval" in attrs and attrs["_schedule_interval"] != JobExecutionType.TYPE_IMMEDIATELY:
797
+ if "_schedule_name" not in attrs:
773
798
  raise serializers.ValidationError({"_schedule_name": "Please provide a name for the job schedule."})
774
799
 
775
- if ("_schedule_start_time" not in data and data["_schedule_interval"] != JobExecutionType.TYPE_CUSTOM) or (
776
- "_schedule_start_time" in data and data["_schedule_start_time"] < ScheduledJob.earliest_possible_time()
800
+ if (
801
+ "_schedule_start_time" not in attrs and attrs["_schedule_interval"] != JobExecutionType.TYPE_CUSTOM
802
+ ) or (
803
+ "_schedule_start_time" in attrs
804
+ and attrs["_schedule_start_time"] < ScheduledJob.earliest_possible_time()
777
805
  ):
778
806
  raise serializers.ValidationError(
779
807
  {
@@ -781,15 +809,15 @@ class JobMultiPartInputSerializer(serializers.Serializer):
781
809
  }
782
810
  )
783
811
 
784
- if data["_schedule_interval"] == JobExecutionType.TYPE_CUSTOM:
785
- if data.get("_schedule_crontab") is None:
812
+ if attrs["_schedule_interval"] == JobExecutionType.TYPE_CUSTOM:
813
+ if attrs.get("_schedule_crontab") is None:
786
814
  raise serializers.ValidationError({"_schedule_crontab": "Please enter a valid crontab."})
787
815
  try:
788
- ScheduledJob.get_crontab(data["_schedule_crontab"])
816
+ ScheduledJob.get_crontab(attrs["_schedule_crontab"])
789
817
  except Exception as e:
790
818
  raise serializers.ValidationError({"_schedule_crontab": e})
791
819
 
792
- return data
820
+ return attrs
793
821
 
794
822
 
795
823
  class JobLogEntrySerializer(BaseModelSerializer):
@@ -816,7 +844,7 @@ class JobButtonSerializer(ValidatedModelSerializer, NotesSerializerMixin):
816
844
  #
817
845
 
818
846
 
819
- class MetadataTypeSerializer(NautobotModelSerializer):
847
+ class MetadataTypeSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
820
848
  content_types = ContentTypeField(
821
849
  queryset=ContentType.objects.filter(FeatureQuery("metadata").get_query()),
822
850
  many=True,
@@ -1073,18 +1101,18 @@ class TagSerializer(NautobotModelSerializer):
1073
1101
  "color": {"help_text": "RGB color in hexadecimal (e.g. 00ff00)"},
1074
1102
  }
1075
1103
 
1076
- def validate(self, data):
1077
- data = super().validate(data)
1104
+ def validate(self, attrs):
1105
+ attrs = super().validate(attrs)
1078
1106
 
1079
1107
  # check if tag is assigned to any of the removed content_types
1080
- if self.instance is not None and self.instance.present_in_database and "content_types" in data:
1081
- content_types_id = [content_type.id for content_type in data["content_types"]]
1108
+ if self.instance is not None and self.instance.present_in_database and "content_types" in attrs:
1109
+ content_types_id = [content_type.id for content_type in attrs["content_types"]]
1082
1110
  errors = self.instance.validate_content_types_removal(content_types_id)
1083
1111
 
1084
1112
  if errors:
1085
1113
  raise serializers.ValidationError(errors)
1086
1114
 
1087
- return data
1115
+ return attrs
1088
1116
 
1089
1117
 
1090
1118
  #
@@ -1092,9 +1120,7 @@ class TagSerializer(NautobotModelSerializer):
1092
1120
  #
1093
1121
 
1094
1122
 
1095
- class TeamSerializer(NautobotModelSerializer):
1096
- contacts = NautobotHyperlinkedRelatedField(queryset=Contact.objects.all(), many=True, required=False)
1097
-
1123
+ class TeamSerializer(TaggedModelSerializerMixin, NautobotModelSerializer):
1098
1124
  class Meta:
1099
1125
  model = Team
1100
1126
  fields = "__all__"
@@ -1106,10 +1132,10 @@ class TeamSerializer(NautobotModelSerializer):
1106
1132
  # https://www.django-rest-framework.org/api-guide/validators/#optional-fields
1107
1133
  validators = []
1108
1134
 
1109
- def validate(self, data):
1135
+ def validate(self, attrs):
1110
1136
  validator = UniqueTogetherValidator(queryset=Team.objects.all(), fields=("name", "phone", "email"))
1111
- validator(data, self)
1112
- return super().validate(data)
1137
+ validator(attrs, self)
1138
+ return super().validate(attrs)
1113
1139
 
1114
1140
 
1115
1141
  #
@@ -1127,19 +1153,31 @@ class WebhookSerializer(ValidatedModelSerializer, NotesSerializerMixin):
1127
1153
  model = Webhook
1128
1154
  fields = "__all__"
1129
1155
 
1130
- def validate(self, data):
1131
- validated_data = super().validate(data)
1156
+ def validate(self, attrs):
1157
+ validated_attrs = super().validate(attrs)
1132
1158
 
1133
1159
  conflicts = Webhook.check_for_conflicts(
1134
1160
  instance=self.instance,
1135
- content_types=data.get("content_types"),
1136
- payload_url=data.get("payload_url"),
1137
- type_create=data.get("type_create"),
1138
- type_update=data.get("type_update"),
1139
- type_delete=data.get("type_delete"),
1161
+ content_types=attrs.get("content_types"),
1162
+ payload_url=attrs.get("payload_url"),
1163
+ type_create=attrs.get("type_create"),
1164
+ type_update=attrs.get("type_update"),
1165
+ type_delete=attrs.get("type_delete"),
1140
1166
  )
1141
1167
 
1142
1168
  if conflicts:
1143
1169
  raise serializers.ValidationError(conflicts)
1144
1170
 
1145
- return validated_data
1171
+ return validated_attrs
1172
+
1173
+
1174
+ #
1175
+ # More Git repositories
1176
+ #
1177
+
1178
+
1179
+ class GitRepositorySyncResponseSerializer(serializers.Serializer):
1180
+ """Serializer representing responses from the GitRepository.sync() POST endpoint."""
1181
+
1182
+ message = serializers.CharField(read_only=True)
1183
+ job_result = JobResultSerializer(read_only=True)
@@ -17,6 +17,7 @@ from rest_framework.permissions import IsAuthenticated
17
17
  from rest_framework.response import Response
18
18
 
19
19
  from nautobot.core.api.authentication import TokenPermissions
20
+ from nautobot.core.api.parsers import NautobotCSVParser
20
21
  from nautobot.core.api.utils import get_serializer_for_model
21
22
  from nautobot.core.api.views import (
22
23
  BulkDestroyModelMixin,
@@ -180,14 +181,7 @@ class ConfigContextQuerySetMixin:
180
181
 
181
182
 
182
183
  class ConfigContextViewSet(NotesViewSetMixin, ModelViewSet):
183
- queryset = ConfigContext.objects.prefetch_related(
184
- "locations",
185
- "roles",
186
- "device_types",
187
- "platforms",
188
- "tenant_groups",
189
- "tenants",
190
- )
184
+ queryset = ConfigContext.objects.all()
191
185
  serializer_class = serializers.ConfigContextSerializer
192
186
  filterset_class = filters.ConfigContextFilterSet
193
187
 
@@ -304,7 +298,7 @@ class DynamicGroupViewSet(NotesViewSetMixin, ModelViewSet):
304
298
  Manage Dynamic Groups through DELETE, GET, POST, PUT, and PATCH requests.
305
299
  """
306
300
 
307
- queryset = DynamicGroup.objects.select_related("content_type")
301
+ queryset = DynamicGroup.objects.all()
308
302
  serializer_class = serializers.DynamicGroupSerializer
309
303
  filterset_class = filters.DynamicGroupFilterSet
310
304
 
@@ -329,7 +323,7 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
329
323
  Manage Dynamic Group Memberships through DELETE, GET, POST, PUT, and PATCH requests.
330
324
  """
331
325
 
332
- queryset = DynamicGroupMembership.objects.select_related("group", "parent_group")
326
+ queryset = DynamicGroupMembership.objects.all()
333
327
  serializer_class = serializers.DynamicGroupMembershipSerializer
334
328
  filterset_class = filters.DynamicGroupMembershipFilterSet
335
329
 
@@ -340,13 +334,13 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
340
334
 
341
335
 
342
336
  class SavedViewViewSet(ModelViewSet):
343
- queryset = SavedView.objects.select_related("owner")
337
+ queryset = SavedView.objects.all()
344
338
  serializer_class = serializers.SavedViewSerializer
345
339
  filterset_class = filters.SavedViewFilterSet
346
340
 
347
341
 
348
342
  class UserSavedViewAssociationViewSet(ModelViewSet):
349
- queryset = UserSavedViewAssociation.objects.select_related("user", "saved_view")
343
+ queryset = UserSavedViewAssociation.objects.all()
350
344
  serializer_class = serializers.UserSavedViewAssociationSerializer
351
345
  filterset_class = filters.UserSavedViewAssociationFilterSet
352
346
 
@@ -356,7 +350,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
356
350
  Manage Static Group Associations through DELETE, GET, POST, PUT, and PATCH requests.
357
351
  """
358
352
 
359
- queryset = StaticGroupAssociation.objects.select_related("associated_object_type", "dynamic_group")
353
+ queryset = StaticGroupAssociation.objects.all()
360
354
  serializer_class = serializers.StaticGroupAssociationSerializer
361
355
  filterset_class = filters.StaticGroupAssociationFilterSet
362
356
 
@@ -367,7 +361,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
367
361
  and "dynamic_group" in self.request.GET
368
362
  and self.action in ["list", "retrieve"]
369
363
  ):
370
- self.queryset = StaticGroupAssociation.all_objects.select_related("associated_object_type", "dynamic_group")
364
+ self.queryset = StaticGroupAssociation.all_objects.all()
371
365
  return super().get_queryset()
372
366
 
373
367
 
@@ -388,7 +382,7 @@ class ExportTemplateViewSet(NotesViewSetMixin, ModelViewSet):
388
382
 
389
383
 
390
384
  class ExternalIntegrationViewSet(NautobotModelViewSet):
391
- queryset = ExternalIntegration.objects.select_related("secrets_group")
385
+ queryset = ExternalIntegration.objects.all()
392
386
  serializer_class = serializers.ExternalIntegrationSerializer
393
387
  filterset_class = filters.ExternalIntegrationFilterSet
394
388
 
@@ -399,7 +393,7 @@ class ExternalIntegrationViewSet(NautobotModelViewSet):
399
393
 
400
394
 
401
395
  class FileProxyViewSet(ReadOnlyModelViewSet):
402
- queryset = FileProxy.objects.select_related("job_result")
396
+ queryset = FileProxy.objects.all()
403
397
  serializer_class = serializers.FileProxySerializer
404
398
  filterset_class = filters.FileProxyFilterSet
405
399
 
@@ -431,7 +425,7 @@ class GitRepositoryViewSet(NautobotModelViewSet):
431
425
  serializer_class = serializers.GitRepositorySerializer
432
426
  filterset_class = filters.GitRepositoryFilterSet
433
427
 
434
- @extend_schema(methods=["post"], request=serializers.GitRepositorySerializer)
428
+ @extend_schema(methods=["post"], responses={"200": serializers.GitRepositorySyncResponseSerializer}, request=None)
435
429
  # Since we are explicitly checking for `extras:change_gitrepository` in the API sync() method
436
430
  # We explicitly set the permission_classes to IsAuthenticated in the @action decorator
437
431
  # bypassing the default DRF permission check for `extras:add_gitrepository` and the permission check fall through to the function itself.
@@ -447,8 +441,16 @@ class GitRepositoryViewSet(NautobotModelViewSet):
447
441
  raise CeleryWorkerNotRunningException()
448
442
 
449
443
  repository = get_object_or_404(GitRepository, id=pk)
450
- repository.sync(user=request.user)
451
- return Response({"message": f"Repository {repository} sync job added to queue."})
444
+ job_result = repository.sync(user=request.user)
445
+
446
+ data = {
447
+ # Kept message for backward compatibility for now
448
+ "message": f"Repository {repository} sync job added to queue.",
449
+ "job_result": job_result,
450
+ }
451
+
452
+ serializer = serializers.GitRepositorySyncResponseSerializer(data, context={"request": request})
453
+ return Response(serializer.data, status=status.HTTP_200_OK)
452
454
 
453
455
 
454
456
  #
@@ -488,6 +490,7 @@ class ImageAttachmentViewSet(ModelViewSet):
488
490
  queryset = ImageAttachment.objects.all()
489
491
  serializer_class = serializers.ImageAttachmentSerializer
490
492
  filterset_class = filters.ImageAttachmentFilterSet
493
+ parser_classes = [JSONParser, NautobotCSVParser, MultiPartParser]
491
494
 
492
495
 
493
496
  #
@@ -766,13 +769,13 @@ class JobViewSet(
766
769
  ):
767
770
  lookup_value_regex = r"[-0-9a-fA-F]+"
768
771
 
769
- def perform_destroy(self, obj):
770
- if obj.module_name.startswith("nautobot."):
772
+ def perform_destroy(self, instance):
773
+ if instance.module_name.startswith("nautobot."):
771
774
  raise ProtectedError(
772
- f"Unable to delete Job {obj}. System Job cannot be deleted",
775
+ f"Unable to delete Job {instance}. System Job cannot be deleted",
773
776
  [],
774
777
  )
775
- super().perform_destroy(obj)
778
+ super().perform_destroy(instance)
776
779
 
777
780
 
778
781
  @extend_schema_view(
@@ -838,7 +841,7 @@ class JobQueueAssignmentViewSet(NautobotModelViewSet):
838
841
  Manage job queue assignments through DELETE, GET, POST, PUT, and PATCH requests.
839
842
  """
840
843
 
841
- queryset = JobQueueAssignment.objects.select_related("job", "job_queue")
844
+ queryset = JobQueueAssignment.objects.all()
842
845
  serializer_class = serializers.JobQueueAssignmentSerializer
843
846
  filterset_class = filters.JobQueueAssignmentFilterSet
844
847
 
@@ -853,7 +856,7 @@ class JobLogEntryViewSet(ReadOnlyModelViewSet):
853
856
  Retrieve a list of job log entries.
854
857
  """
855
858
 
856
- queryset = JobLogEntry.objects.select_related("job_result")
859
+ queryset = JobLogEntry.objects.all()
857
860
  serializer_class = serializers.JobLogEntrySerializer
858
861
  filterset_class = filters.JobLogEntryFilterSet
859
862
 
@@ -871,7 +874,7 @@ class JobResultViewSet(
871
874
  Retrieve a list of job results
872
875
  """
873
876
 
874
- queryset = JobResult.objects.select_related("job_model", "user")
877
+ queryset = JobResult.objects.all()
875
878
  serializer_class = serializers.JobResultSerializer
876
879
  filterset_class = filters.JobResultFilterSet
877
880
 
@@ -908,7 +911,7 @@ class ScheduledJobViewSet(ReadOnlyModelViewSet):
908
911
  Retrieve a list of scheduled jobs
909
912
  """
910
913
 
911
- queryset = ScheduledJob.objects.select_related("user")
914
+ queryset = ScheduledJob.objects.all()
912
915
  serializer_class = serializers.ScheduledJobSerializer
913
916
  filterset_class = filters.ScheduledJobFilterSet
914
917
 
@@ -1061,7 +1064,7 @@ class MetadataTypeViewSet(NautobotModelViewSet):
1061
1064
 
1062
1065
 
1063
1066
  class MetadataChoiceViewSet(ModelViewSet):
1064
- queryset = MetadataChoice.objects.select_related("metadata_type")
1067
+ queryset = MetadataChoice.objects.all()
1065
1068
  serializer_class = serializers.MetadataChoiceSerializer
1066
1069
  filterset_class = filters.MetadataChoiceFilterSet
1067
1070
 
@@ -1078,7 +1081,7 @@ class ObjectMetadataViewSet(NautobotModelViewSet):
1078
1081
 
1079
1082
 
1080
1083
  class NoteViewSet(ModelViewSet):
1081
- queryset = Note.objects.select_related("user")
1084
+ queryset = Note.objects.all()
1082
1085
  serializer_class = serializers.NoteSerializer
1083
1086
  filterset_class = filters.NoteFilterSet
1084
1087
 
@@ -1097,7 +1100,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
1097
1100
  Retrieve a list of recent changes.
1098
1101
  """
1099
1102
 
1100
- queryset = ObjectChange.objects.select_related("user")
1103
+ queryset = ObjectChange.objects.all()
1101
1104
  serializer_class = serializers.ObjectChangeSerializer
1102
1105
  filterset_class = filters.ObjectChangeFilterSet
1103
1106
 
@@ -11,6 +11,7 @@ EXTRAS_FEATURES = [
11
11
  "dynamic_groups",
12
12
  "export_template_owners",
13
13
  "export_templates",
14
+ "graphql_query_owners",
14
15
  "graphql",
15
16
  "job_results", # No longer used
16
17
  "locations",
@@ -30,6 +31,7 @@ JOB_OVERRIDABLE_FIELDS = (
30
31
  "soft_time_limit",
31
32
  "time_limit",
32
33
  "has_sensitive_variables",
34
+ "is_singleton",
33
35
  )
34
36
 
35
37
 
@@ -52,4 +54,5 @@ JOB_RESULT_CUSTOM_CELERY_KWARGS = (
52
54
  "nautobot_job_job_model_id",
53
55
  "nautobot_job_scheduled_job_id",
54
56
  "nautobot_job_user_id",
57
+ "nautobot_job_ignore_singleton_lock",
55
58
  )