nautobot 2.3.16__py3-none-any.whl → 2.4.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.

Potentially problematic release.


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

Files changed (675) hide show
  1. nautobot/__init__.py +15 -0
  2. nautobot/apps/api.py +0 -2
  3. nautobot/apps/config.py +32 -3
  4. nautobot/apps/events.py +19 -0
  5. nautobot/apps/exceptions.py +0 -2
  6. nautobot/apps/ui.py +44 -9
  7. nautobot/apps/utils.py +0 -8
  8. nautobot/apps/views.py +2 -0
  9. nautobot/circuits/navigation.py +0 -57
  10. nautobot/circuits/tables.py +1 -2
  11. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
  12. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
  13. nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
  15. nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
  16. nautobot/circuits/tests/integration/test_relationships.py +33 -24
  17. nautobot/circuits/tests/test_filters.py +4 -8
  18. nautobot/circuits/views.py +143 -26
  19. nautobot/cloud/factory.py +4 -1
  20. nautobot/cloud/models.py +1 -1
  21. nautobot/cloud/tests/test_filters.py +5 -4
  22. nautobot/core/api/fields.py +5 -5
  23. nautobot/core/api/metadata.py +28 -256
  24. nautobot/core/api/pagination.py +3 -2
  25. nautobot/core/api/renderers.py +3 -0
  26. nautobot/core/api/serializers.py +24 -244
  27. nautobot/core/api/urls.py +3 -4
  28. nautobot/core/api/utils.py +0 -62
  29. nautobot/core/api/views.py +48 -158
  30. nautobot/core/apps/__init__.py +22 -578
  31. nautobot/core/celery/__init__.py +13 -0
  32. nautobot/core/celery/log.py +4 -4
  33. nautobot/core/celery/schedulers.py +48 -3
  34. nautobot/core/cli/__init__.py +8 -0
  35. nautobot/core/constants.py +7 -0
  36. nautobot/core/events/__init__.py +116 -0
  37. nautobot/core/events/base.py +27 -0
  38. nautobot/core/events/exceptions.py +10 -0
  39. nautobot/core/events/redis_broker.py +48 -0
  40. nautobot/core/events/syslog_broker.py +19 -0
  41. nautobot/core/exceptions.py +0 -6
  42. nautobot/core/filters.py +16 -21
  43. nautobot/core/fixtures/user-data.json +59 -0
  44. nautobot/core/forms/fields.py +53 -8
  45. nautobot/core/forms/utils.py +2 -1
  46. nautobot/core/graphql/schema.py +3 -1
  47. nautobot/core/graphql/types.py +1 -1
  48. nautobot/core/jobs/__init__.py +4 -4
  49. nautobot/core/jobs/cleanup.py +13 -49
  50. nautobot/core/jobs/groups.py +1 -1
  51. nautobot/core/management/commands/generate_test_data.py +21 -0
  52. nautobot/core/management/commands/validate_models.py +1 -1
  53. nautobot/core/middleware.py +16 -0
  54. nautobot/core/models/__init__.py +1 -1
  55. nautobot/core/models/fields.py +11 -7
  56. nautobot/core/models/query_functions.py +2 -2
  57. nautobot/core/models/tree_queries.py +3 -6
  58. nautobot/core/settings.py +44 -7
  59. nautobot/core/settings.yaml +86 -8
  60. nautobot/core/tables.py +15 -65
  61. nautobot/core/tasks.py +1 -1
  62. nautobot/core/templates/components/button/default.html +7 -0
  63. nautobot/core/templates/components/button/dropdown.html +20 -0
  64. nautobot/core/templates/components/layout/one_over_two.html +19 -0
  65. nautobot/core/templates/components/layout/two_over_one.html +19 -0
  66. nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
  67. nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
  68. nautobot/core/templates/components/panel/body_content_tags.html +6 -0
  69. nautobot/core/templates/components/panel/body_content_text.html +12 -0
  70. nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
  71. nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
  72. nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
  73. nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
  74. nautobot/core/templates/components/panel/footer_content_table.html +14 -0
  75. nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
  76. nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
  77. nautobot/core/templates/components/panel/panel.html +16 -0
  78. nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
  79. nautobot/core/templates/components/tab/content_wrapper.html +3 -0
  80. nautobot/core/templates/components/tab/label_wrapper.html +5 -0
  81. nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
  82. nautobot/core/templates/generic/object_retrieve.html +28 -17
  83. nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
  84. nautobot/core/templates/inc/custom_fields/panel.html +2 -2
  85. nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
  86. nautobot/core/templates/inc/footer.html +1 -0
  87. nautobot/core/templates/inc/media.html +0 -3
  88. nautobot/core/templates/inc/nav_menu.html +1 -1
  89. nautobot/core/templates/inc/relationships_panel.html +1 -1
  90. nautobot/core/templates/nautobot_config.py.j2 +3 -3
  91. nautobot/core/templates/panel_table.html +12 -0
  92. nautobot/core/templates/search.html +0 -7
  93. nautobot/core/templates/utilities/render_jinja2.html +117 -0
  94. nautobot/core/templatetags/helpers.py +101 -12
  95. nautobot/core/templatetags/ui_framework.py +40 -0
  96. nautobot/core/testing/api.py +23 -128
  97. nautobot/core/testing/context.py +18 -0
  98. nautobot/core/testing/filters.py +41 -58
  99. nautobot/core/testing/mixins.py +2 -7
  100. nautobot/core/testing/views.py +25 -123
  101. nautobot/core/tests/integration/test_app_home.py +1 -0
  102. nautobot/core/tests/integration/test_app_navbar.py +1 -0
  103. nautobot/core/tests/integration/test_filters.py +2 -0
  104. nautobot/core/tests/integration/test_home.py +1 -0
  105. nautobot/core/tests/integration/test_navbar.py +1 -0
  106. nautobot/core/tests/integration/test_view_authentication.py +1 -2
  107. nautobot/core/tests/nautobot_config.py +198 -0
  108. nautobot/core/tests/runner.py +3 -3
  109. nautobot/core/tests/test_api.py +82 -201
  110. nautobot/core/tests/test_csv.py +3 -25
  111. nautobot/core/tests/test_events.py +214 -0
  112. nautobot/core/tests/test_jinja_filters.py +1 -0
  113. nautobot/core/tests/test_jobs.py +84 -13
  114. nautobot/core/tests/test_navigations.py +7 -241
  115. nautobot/core/tests/test_templatetags_helpers.py +16 -0
  116. nautobot/core/tests/test_ui.py +150 -0
  117. nautobot/core/tests/test_utils.py +0 -25
  118. nautobot/core/tests/test_views.py +123 -31
  119. nautobot/core/ui/__init__.py +0 -0
  120. nautobot/core/ui/base.py +11 -0
  121. nautobot/core/ui/choices.py +44 -0
  122. nautobot/core/ui/homepage.py +167 -0
  123. nautobot/core/ui/nav.py +279 -0
  124. nautobot/core/ui/object_detail.py +1841 -0
  125. nautobot/core/ui/utils.py +36 -0
  126. nautobot/core/urls.py +4 -9
  127. nautobot/core/utils/config.py +30 -3
  128. nautobot/core/utils/lookup.py +20 -13
  129. nautobot/core/views/__init__.py +6 -1
  130. nautobot/core/views/generic.py +47 -52
  131. nautobot/core/views/mixins.py +15 -25
  132. nautobot/core/views/paginator.py +8 -5
  133. nautobot/core/views/renderers.py +3 -3
  134. nautobot/core/views/utils.py +11 -0
  135. nautobot/core/wsgi.py +3 -3
  136. nautobot/dcim/api/serializers.py +80 -179
  137. nautobot/dcim/api/urls.py +5 -0
  138. nautobot/dcim/api/views.py +17 -4
  139. nautobot/dcim/apps.py +1 -0
  140. nautobot/dcim/choices.py +28 -0
  141. nautobot/dcim/factory.py +58 -0
  142. nautobot/dcim/filters/__init__.py +197 -24
  143. nautobot/dcim/forms.py +203 -12
  144. nautobot/dcim/graphql/types.py +2 -2
  145. nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
  146. nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
  147. nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
  148. nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
  149. nautobot/dcim/models/__init__.py +4 -0
  150. nautobot/dcim/models/device_component_templates.py +2 -2
  151. nautobot/dcim/models/device_components.py +20 -22
  152. nautobot/dcim/models/devices.py +173 -4
  153. nautobot/dcim/models/locations.py +3 -3
  154. nautobot/dcim/models/power.py +5 -6
  155. nautobot/dcim/models/racks.py +6 -6
  156. nautobot/dcim/navigation.py +25 -224
  157. nautobot/dcim/signals.py +44 -0
  158. nautobot/dcim/tables/__init__.py +5 -3
  159. nautobot/dcim/tables/devices.py +96 -2
  160. nautobot/dcim/tables/devicetypes.py +2 -2
  161. nautobot/dcim/templates/dcim/controller/base.html +10 -0
  162. nautobot/dcim/templates/dcim/controller_create.html +1 -0
  163. nautobot/dcim/templates/dcim/controller_retrieve.html +5 -1
  164. nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
  165. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +66 -0
  166. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +46 -0
  167. nautobot/dcim/templates/dcim/device/base.html +6 -42
  168. nautobot/dcim/templates/dcim/device/wireless.html +73 -0
  169. nautobot/dcim/templates/dcim/device.html +3 -1
  170. nautobot/dcim/templates/dcim/interface.html +1 -0
  171. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  172. nautobot/dcim/templates/dcim/locationtype.html +0 -107
  173. nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
  174. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +76 -0
  175. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +34 -0
  176. nautobot/dcim/tests/test_api.py +172 -61
  177. nautobot/dcim/tests/test_filters.py +171 -109
  178. nautobot/dcim/tests/test_forms.py +2 -51
  179. nautobot/dcim/tests/test_graphql.py +0 -52
  180. nautobot/dcim/tests/test_models.py +126 -4
  181. nautobot/dcim/tests/test_signals.py +1 -0
  182. nautobot/dcim/tests/test_views.py +103 -11
  183. nautobot/dcim/urls.py +72 -27
  184. nautobot/dcim/utils.py +2 -2
  185. nautobot/dcim/views.py +369 -62
  186. nautobot/extras/api/customfields.py +2 -2
  187. nautobot/extras/api/serializers.py +91 -75
  188. nautobot/extras/api/urls.py +4 -0
  189. nautobot/extras/api/views.py +78 -15
  190. nautobot/extras/choices.py +13 -0
  191. nautobot/extras/constants.py +0 -1
  192. nautobot/extras/context_managers.py +23 -6
  193. nautobot/extras/datasources/git.py +4 -1
  194. nautobot/extras/factory.py +27 -0
  195. nautobot/extras/filters/__init__.py +59 -0
  196. nautobot/extras/forms/forms.py +125 -30
  197. nautobot/extras/forms/mixins.py +3 -11
  198. nautobot/extras/graphql/types.py +25 -1
  199. nautobot/extras/group_sync.py +3 -3
  200. nautobot/extras/health_checks.py +2 -1
  201. nautobot/extras/jobs.py +62 -26
  202. nautobot/extras/management/__init__.py +1 -0
  203. nautobot/extras/management/commands/runjob.py +7 -79
  204. nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
  205. nautobot/extras/management/utils.py +87 -0
  206. nautobot/extras/managers.py +1 -3
  207. nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
  208. nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
  209. nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
  210. nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
  211. nautobot/extras/models/__init__.py +4 -0
  212. nautobot/extras/models/change_logging.py +7 -3
  213. nautobot/extras/models/customfields.py +11 -12
  214. nautobot/extras/models/groups.py +9 -13
  215. nautobot/extras/models/jobs.py +218 -37
  216. nautobot/extras/models/models.py +2 -2
  217. nautobot/extras/models/relationships.py +69 -1
  218. nautobot/extras/models/secrets.py +5 -0
  219. nautobot/extras/navigation.py +20 -262
  220. nautobot/extras/plugins/__init__.py +56 -32
  221. nautobot/extras/plugins/marketplace_manifest.yml +450 -0
  222. nautobot/extras/plugins/urls.py +1 -0
  223. nautobot/extras/plugins/views.py +48 -1
  224. nautobot/extras/signals.py +39 -1
  225. nautobot/extras/tables.py +40 -6
  226. nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
  227. nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
  228. nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
  229. nautobot/extras/templates/extras/job_detail.html +36 -6
  230. nautobot/extras/templates/extras/job_edit.html +5 -2
  231. nautobot/extras/templates/extras/job_list.html +2 -7
  232. nautobot/extras/templates/extras/jobqueue_retrieve.html +44 -0
  233. nautobot/extras/templates/extras/marketplace.html +278 -0
  234. nautobot/extras/templates/extras/plugins_list.html +35 -1
  235. nautobot/extras/templates/extras/plugins_tiles.html +79 -0
  236. nautobot/extras/templates/extras/role_retrieve.html +16 -0
  237. nautobot/extras/templates/extras/secret.html +0 -65
  238. nautobot/extras/templates/extras/secret_check.js +16 -0
  239. nautobot/extras/templates/extras/secret_create.html +114 -0
  240. nautobot/extras/templates/extras/secret_edit.html +1 -114
  241. nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
  242. nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
  243. nautobot/extras/templatetags/job_buttons.py +5 -4
  244. nautobot/extras/templatetags/plugins.py +69 -6
  245. nautobot/extras/test_jobs/api_test_job.py +1 -1
  246. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  247. nautobot/extras/test_jobs/dry_run.py +1 -1
  248. nautobot/extras/test_jobs/fail.py +5 -5
  249. nautobot/extras/test_jobs/file_output.py +1 -1
  250. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  251. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  252. nautobot/extras/test_jobs/ipaddress_vars.py +1 -3
  253. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  254. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  255. nautobot/extras/test_jobs/log_redaction.py +1 -1
  256. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  257. nautobot/extras/test_jobs/modify_db.py +1 -1
  258. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  259. nautobot/extras/test_jobs/object_var_required.py +1 -1
  260. nautobot/extras/test_jobs/object_vars.py +1 -1
  261. nautobot/extras/test_jobs/pass.py +3 -3
  262. nautobot/extras/test_jobs/profiling.py +1 -1
  263. nautobot/extras/test_jobs/relative_import.py +3 -3
  264. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  265. nautobot/extras/test_jobs/task_queues.py +1 -1
  266. nautobot/extras/tests/integration/test_plugin_banner.py +2 -0
  267. nautobot/extras/tests/test_api.py +157 -55
  268. nautobot/extras/tests/test_context_managers.py +4 -1
  269. nautobot/extras/tests/test_customfields.py +1 -1
  270. nautobot/extras/tests/test_datasources.py +1 -2
  271. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  272. nautobot/extras/tests/test_filters.py +219 -535
  273. nautobot/extras/tests/test_forms.py +1 -20
  274. nautobot/extras/tests/test_job_variables.py +73 -152
  275. nautobot/extras/tests/test_jobs.py +43 -54
  276. nautobot/extras/tests/test_models.py +71 -16
  277. nautobot/extras/tests/test_relationships.py +5 -2
  278. nautobot/extras/tests/test_utils.py +23 -2
  279. nautobot/extras/tests/test_views.py +183 -43
  280. nautobot/extras/tests/test_webhooks.py +2 -1
  281. nautobot/extras/urls.py +2 -20
  282. nautobot/extras/utils.py +118 -4
  283. nautobot/extras/views.py +203 -92
  284. nautobot/extras/webhooks.py +5 -2
  285. nautobot/ipam/api/fields.py +3 -3
  286. nautobot/ipam/api/serializers.py +36 -137
  287. nautobot/ipam/api/views.py +93 -62
  288. nautobot/ipam/lookups.py +62 -101
  289. nautobot/ipam/models.py +11 -63
  290. nautobot/ipam/navigation.py +0 -90
  291. nautobot/ipam/querysets.py +2 -2
  292. nautobot/ipam/tables.py +6 -20
  293. nautobot/ipam/templates/ipam/routetarget.html +0 -28
  294. nautobot/ipam/templates/ipam/vrf.html +0 -47
  295. nautobot/ipam/tests/test_api.py +8 -419
  296. nautobot/ipam/tests/test_filters.py +39 -119
  297. nautobot/ipam/tests/test_forms.py +47 -51
  298. nautobot/ipam/tests/test_migrations.py +30 -30
  299. nautobot/ipam/tests/test_models.py +0 -41
  300. nautobot/ipam/tests/test_querysets.py +1 -63
  301. nautobot/ipam/urls.py +3 -69
  302. nautobot/ipam/utils/__init__.py +0 -24
  303. nautobot/ipam/views.py +153 -198
  304. nautobot/project-static/css/base.css +38 -3
  305. nautobot/project-static/docs/404.html +421 -19
  306. nautobot/project-static/docs/apps/index.html +421 -19
  307. nautobot/project-static/docs/apps/nautobot-apps.html +421 -19
  308. nautobot/project-static/docs/assets/extra.css +5 -1
  309. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
  310. nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
  311. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +421 -19
  312. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +421 -19
  313. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +421 -172
  314. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +421 -19
  315. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +421 -19
  316. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +425 -21
  317. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +421 -19
  318. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +424 -22
  319. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9809 -0
  320. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +424 -63
  321. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +421 -19
  322. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +421 -19
  323. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +457 -20
  324. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +421 -19
  325. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +425 -25
  326. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +457 -19
  327. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +421 -19
  328. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +421 -19
  329. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +425 -215
  330. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +430 -342
  331. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5799 -1054
  332. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +421 -19
  333. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +447 -176
  334. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +460 -21
  335. nautobot/project-static/docs/development/apps/api/configuration-view.html +421 -19
  336. nautobot/project-static/docs/development/apps/api/database-backend-config.html +421 -19
  337. nautobot/project-static/docs/development/apps/api/models/django-admin.html +421 -19
  338. nautobot/project-static/docs/development/apps/api/models/global-search.html +421 -19
  339. nautobot/project-static/docs/development/apps/api/models/graphql.html +421 -19
  340. nautobot/project-static/docs/development/apps/api/models/index.html +421 -19
  341. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +421 -19
  342. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +421 -19
  343. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +421 -19
  344. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +421 -19
  345. nautobot/project-static/docs/development/apps/api/platform-features/index.html +421 -19
  346. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +421 -19
  347. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +421 -19
  348. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +421 -19
  349. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +421 -19
  350. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +424 -41
  351. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +421 -19
  352. nautobot/project-static/docs/development/apps/api/prometheus.html +421 -19
  353. nautobot/project-static/docs/development/apps/api/setup.html +425 -155
  354. nautobot/project-static/docs/development/apps/api/testing.html +421 -19
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +421 -19
  356. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +421 -19
  357. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +421 -19
  358. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +421 -19
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +701 -130
  360. nautobot/project-static/docs/development/apps/api/views/base-template.html +421 -19
  361. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +421 -19
  362. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +421 -19
  363. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +421 -19
  364. nautobot/project-static/docs/development/apps/api/views/index.html +423 -20
  365. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +425 -19
  366. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +451 -19
  367. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +421 -19
  368. nautobot/project-static/docs/development/apps/api/views/notes.html +421 -19
  369. nautobot/project-static/docs/development/apps/api/views/rest-api.html +421 -19
  370. nautobot/project-static/docs/development/apps/api/views/urls.html +421 -19
  371. nautobot/project-static/docs/development/apps/index.html +421 -19
  372. nautobot/project-static/docs/development/apps/migration/code-updates.html +422 -52
  373. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +422 -20
  374. nautobot/project-static/docs/development/apps/migration/from-v1.html +421 -19
  375. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +421 -19
  376. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +421 -19
  377. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +421 -19
  378. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +424 -22
  379. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9219 -0
  380. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9333 -0
  381. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9474 -0
  382. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9517 -0
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +424 -22
  384. nautobot/project-static/docs/development/core/application-registry.html +421 -19
  385. nautobot/project-static/docs/development/core/best-practices.html +421 -19
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +421 -19
  387. nautobot/project-static/docs/development/core/caching.html +421 -19
  388. nautobot/project-static/docs/development/core/controllers.html +423 -19
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +490 -45
  390. nautobot/project-static/docs/development/core/generic-views.html +421 -19
  391. nautobot/project-static/docs/development/core/getting-started.html +566 -179
  392. nautobot/project-static/docs/development/core/homepage.html +432 -30
  393. nautobot/project-static/docs/development/core/index.html +421 -19
  394. nautobot/project-static/docs/development/core/local-k8s.html +9453 -0
  395. nautobot/project-static/docs/development/core/model-checklist.html +424 -22
  396. nautobot/project-static/docs/development/core/model-features.html +421 -19
  397. nautobot/project-static/docs/development/core/natural-keys.html +421 -19
  398. nautobot/project-static/docs/development/core/navigation-menu.html +438 -26
  399. nautobot/project-static/docs/development/core/release-checklist.html +435 -45
  400. nautobot/project-static/docs/development/core/role-internals.html +421 -19
  401. nautobot/project-static/docs/development/core/settings.html +421 -19
  402. nautobot/project-static/docs/development/core/style-guide.html +421 -19
  403. nautobot/project-static/docs/development/core/templates.html +431 -22
  404. nautobot/project-static/docs/development/core/testing.html +421 -19
  405. nautobot/project-static/docs/development/core/ui-component-framework.html +11020 -0
  406. nautobot/project-static/docs/development/core/user-preferences.html +424 -22
  407. nautobot/project-static/docs/development/index.html +421 -19
  408. nautobot/project-static/docs/development/jobs/index.html +546 -160
  409. nautobot/project-static/docs/development/jobs/migration/from-v1.html +421 -19
  410. nautobot/project-static/docs/index.html +421 -19
  411. nautobot/project-static/docs/media/development/core/ui-component-framework/basic-panel-layout.png +0 -0
  412. nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.png +0 -0
  413. nautobot/project-static/docs/media/development/core/ui-component-framework/dropdown-button-example.png +0 -0
  414. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
  415. nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
  416. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example.png +0 -0
  417. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
  418. nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
  419. nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
  420. nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
  421. nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
  422. nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
  423. nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
  424. nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
  425. nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
  426. nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
  427. nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +426 -20
  430. nautobot/project-static/docs/overview/design_philosophy.html +421 -19
  431. nautobot/project-static/docs/release-notes/index.html +445 -22
  432. nautobot/project-static/docs/release-notes/version-1.0.html +421 -19
  433. nautobot/project-static/docs/release-notes/version-1.1.html +421 -19
  434. nautobot/project-static/docs/release-notes/version-1.2.html +421 -19
  435. nautobot/project-static/docs/release-notes/version-1.3.html +421 -19
  436. nautobot/project-static/docs/release-notes/version-1.4.html +421 -19
  437. nautobot/project-static/docs/release-notes/version-1.5.html +421 -19
  438. nautobot/project-static/docs/release-notes/version-1.6.html +634 -667
  439. nautobot/project-static/docs/release-notes/version-2.0.html +421 -19
  440. nautobot/project-static/docs/release-notes/version-2.1.html +421 -19
  441. nautobot/project-static/docs/release-notes/version-2.2.html +421 -19
  442. nautobot/project-static/docs/release-notes/version-2.3.html +684 -886
  443. nautobot/project-static/docs/release-notes/version-2.4.html +10007 -0
  444. nautobot/project-static/docs/requirements.txt +2 -2
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +334 -270
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +421 -19
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +421 -19
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +423 -21
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +433 -32
  452. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +421 -19
  453. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +765 -180
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +421 -19
  455. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +421 -19
  456. nautobot/project-static/docs/user-guide/administration/guides/docker.html +434 -29
  457. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +421 -19
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +421 -19
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +421 -19
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +421 -19
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +421 -19
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +421 -19
  463. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +421 -19
  464. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +421 -19
  465. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +421 -19
  466. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +421 -19
  467. nautobot/project-static/docs/user-guide/administration/installation/index.html +426 -20
  468. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +421 -19
  469. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +421 -19
  470. nautobot/project-static/docs/user-guide/administration/installation/services.html +421 -19
  471. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +421 -19
  472. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +442 -41
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +435 -66
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +435 -66
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +421 -19
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +421 -19
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +421 -19
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +421 -19
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +421 -19
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +421 -19
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +421 -19
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +421 -19
  484. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +427 -21
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +421 -19
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +421 -19
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +421 -19
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +421 -19
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +421 -19
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +421 -19
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +421 -19
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +421 -19
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +421 -19
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +421 -19
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +421 -19
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +421 -19
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +421 -19
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +421 -19
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +421 -19
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +421 -19
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +421 -19
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +457 -20
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +447 -22
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +421 -19
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +421 -19
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +421 -19
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +421 -19
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +421 -19
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +421 -19
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +421 -19
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +421 -19
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +421 -19
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +421 -19
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +421 -19
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +421 -19
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +421 -19
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +421 -19
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +421 -19
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +421 -19
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +421 -19
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +421 -19
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +421 -19
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +421 -19
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +421 -19
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +421 -19
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +421 -19
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +421 -19
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +421 -19
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +421 -19
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +421 -19
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +421 -19
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +421 -19
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +421 -19
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +421 -19
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +421 -19
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +421 -19
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +421 -19
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9333 -0
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +424 -22
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +421 -19
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +421 -19
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +421 -19
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +421 -19
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +421 -19
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +421 -19
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +421 -19
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +421 -19
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +421 -19
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +421 -19
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +421 -19
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +421 -19
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +421 -19
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +421 -19
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +421 -19
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +421 -19
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +421 -19
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +421 -19
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +421 -19
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +424 -22
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9271 -0
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9175 -0
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9169 -0
  563. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9235 -0
  564. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +421 -19
  565. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +421 -19
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +421 -19
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +421 -19
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +421 -19
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +421 -19
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +421 -19
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +421 -19
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +421 -19
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +421 -19
  574. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +421 -19
  575. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +421 -19
  576. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +421 -19
  577. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +421 -19
  578. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +421 -19
  579. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +421 -19
  580. nautobot/project-static/docs/user-guide/index.html +421 -19
  581. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +424 -22
  582. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +421 -19
  583. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +421 -19
  584. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +421 -19
  585. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +421 -19
  586. nautobot/project-static/docs/user-guide/platform-functionality/events.html +9575 -0
  587. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +424 -22
  588. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +421 -19
  589. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +421 -19
  590. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +421 -19
  591. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +421 -19
  592. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +421 -19
  593. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +426 -20
  594. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +424 -22
  595. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +421 -19
  596. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +421 -19
  597. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9182 -0
  598. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +424 -22
  599. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +421 -19
  600. nautobot/project-static/docs/user-guide/platform-functionality/note.html +421 -19
  601. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +421 -19
  602. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +424 -22
  603. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9250 -0
  604. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +421 -19
  605. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +421 -19
  606. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +424 -22
  607. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +421 -19
  608. nautobot/project-static/docs/user-guide/platform-functionality/role.html +421 -19
  609. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +421 -19
  610. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +421 -19
  611. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +424 -22
  612. nautobot/project-static/docs/user-guide/platform-functionality/status.html +421 -19
  613. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +421 -19
  614. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +489 -56
  615. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +421 -19
  616. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +421 -19
  617. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +421 -19
  618. nautobot/project-static/img/jinja_logo.svg +97 -0
  619. nautobot/project-static/js/forms.js +5 -0
  620. nautobot/project-static/js/nav_menu.js +2 -1
  621. nautobot/tenancy/api/serializers.py +0 -2
  622. nautobot/tenancy/factory.py +1 -1
  623. nautobot/tenancy/navigation.py +0 -29
  624. nautobot/tenancy/templates/tenancy/tenant.html +4 -91
  625. nautobot/tenancy/tests/test_filters.py +29 -134
  626. nautobot/tenancy/views.py +32 -23
  627. nautobot/users/admin.py +3 -1
  628. nautobot/users/api/serializers.py +4 -5
  629. nautobot/users/api/views.py +1 -1
  630. nautobot/users/forms.py +19 -0
  631. nautobot/users/templates/users/preferences.html +22 -0
  632. nautobot/users/tests/test_filters.py +1 -19
  633. nautobot/users/tests/test_views.py +57 -0
  634. nautobot/users/utils.py +8 -0
  635. nautobot/users/views.py +48 -11
  636. nautobot/virtualization/api/serializers.py +4 -4
  637. nautobot/virtualization/filters.py +2 -20
  638. nautobot/virtualization/navigation.py +0 -48
  639. nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
  640. nautobot/virtualization/tests/test_filters.py +57 -183
  641. nautobot/virtualization/views.py +18 -15
  642. nautobot/wireless/__init__.py +0 -0
  643. nautobot/wireless/api/__init__.py +0 -0
  644. nautobot/wireless/api/serializers.py +44 -0
  645. nautobot/wireless/api/urls.py +20 -0
  646. nautobot/wireless/api/views.py +34 -0
  647. nautobot/wireless/apps.py +8 -0
  648. nautobot/wireless/choices.py +345 -0
  649. nautobot/wireless/factory.py +138 -0
  650. nautobot/wireless/filters.py +167 -0
  651. nautobot/wireless/forms.py +283 -0
  652. nautobot/wireless/homepage.py +19 -0
  653. nautobot/wireless/migrations/0001_initial.py +223 -0
  654. nautobot/wireless/migrations/__init__.py +0 -0
  655. nautobot/wireless/models.py +207 -0
  656. nautobot/wireless/navigation.py +105 -0
  657. nautobot/wireless/tables.py +244 -0
  658. nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
  659. nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
  660. nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
  661. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +64 -0
  662. nautobot/wireless/tests/__init__.py +0 -0
  663. nautobot/wireless/tests/test_api.py +247 -0
  664. nautobot/wireless/tests/test_filters.py +54 -0
  665. nautobot/wireless/tests/test_models.py +22 -0
  666. nautobot/wireless/tests/test_views.py +378 -0
  667. nautobot/wireless/urls.py +13 -0
  668. nautobot/wireless/views.py +129 -0
  669. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +11 -14
  670. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +674 -551
  671. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
  672. nautobot/core/utils/navigation.py +0 -54
  673. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
  674. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
  675. {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,29 +1,42 @@
1
- from abc import ABC, abstractmethod
2
1
  from collections import OrderedDict
3
2
  import logging
4
3
  import os
5
4
 
6
5
  from constance.apps import ConstanceConfig
7
6
  from django.apps import AppConfig, apps as global_apps
8
- from django.contrib.admin.sites import NotRegistered
9
7
  from django.db.models import BigIntegerField, BinaryField, JSONField
10
8
  from django.db.models.signals import post_migrate
11
9
  from django.urls import reverse
12
10
  from django.urls.exceptions import NoReverseMatch
11
+ from django.utils.http import urlencode
13
12
  from django.utils.module_loading import import_string
14
13
  from graphene.types import generic, String
15
14
 
16
- from nautobot.core.choices import ButtonActionColorChoices, ButtonActionIconChoices
17
15
  from nautobot.core.signals import nautobot_database_ready
18
- from nautobot.core.utils.navigation import get_all_new_ui_ready_routes
16
+ from nautobot.core.ui.base import PermissionsMixin # noqa: F401
17
+
18
+ from nautobot.core.ui.homepage import ( # isort: skip # noqa: F401
19
+ HomePageBase,
20
+ HomePageGroup,
21
+ HomePageItem,
22
+ HomePagePanel,
23
+ )
24
+ from nautobot.core.ui.nav import ( # isort: skip # noqa: F401
25
+ NavMenuAddButton,
26
+ NavMenuBase,
27
+ NavMenuButton,
28
+ NavMenuGroup,
29
+ NavMenuImportButton,
30
+ NavMenuItem,
31
+ NavMenuTab,
32
+ NAV_CONTEXT_NAMES,
33
+ )
34
+
19
35
  from nautobot.extras.registry import registry
20
36
 
21
37
  logger = logging.getLogger(__name__)
22
38
  registry["nav_menu"] = {"tabs": {}}
23
- registry["new_ui_nav_menu"] = {}
24
39
  registry["homepage_layout"] = {"panels": {}}
25
- registry["new_ui_ready_routes"] = set()
26
- NAV_CONTEXT_NAMES = ("Inventory", "Networks", "Security", "Automation", "Platform")
27
40
 
28
41
 
29
42
  class NautobotConfig(AppConfig):
@@ -59,19 +72,6 @@ class NautobotConfig(AppConfig):
59
72
  except ImportError:
60
73
  pass
61
74
 
62
- # TODO we should remove this because it is no longer relevant.
63
- try:
64
- navigation = import_string(f"{self.name}.{self.navigation}")
65
- register_new_ui_menu_items(navigation)
66
- except ImportError:
67
- pass
68
-
69
- try:
70
- registry["new_ui_ready_routes"].update(get_all_new_ui_ready_routes())
71
- except NotRegistered:
72
- # NOTE: Catch this error: The "Tag" model is not registered, which may be related to the admin not registering Tags. Further research is needed on this.
73
- pass
74
-
75
75
 
76
76
  def create_or_check_entry(grouping, record, key, path):
77
77
  """
@@ -96,14 +96,6 @@ def create_or_check_entry(grouping, record, key, path):
96
96
  if grouping[key][attr] != value:
97
97
  logger.error("Unable to redefine %s on %s from %s to %s", attr, path, grouping[key][attr], value)
98
98
 
99
- # TODO: remove?
100
- # React-UI specific: recursive population/validation of `data` for NavContext -> NavGrouping -> NavItem records
101
- if isinstance(record, (NavContext, NavGrouping)):
102
- groups = record.groups if isinstance(record, NavContext) else record.items
103
- for item in groups:
104
- create_or_check_entry(grouping[key]["data"], item, item.name, f"{path} -> {item.name}")
105
- grouping[key]["data"] = dict(sorted(grouping[key]["data"].items(), key=lambda x: x[1]["weight"]))
106
-
107
99
 
108
100
  def register_menu_items(tab_list):
109
101
  """
@@ -174,6 +166,8 @@ def register_menu_items(tab_list):
174
166
  # Instead of passing the reverse url strings, we pass in the url itself initialized with args and kwargs.
175
167
  try:
176
168
  item.link = reverse(item.link, args=item.args, kwargs=item.kwargs)
169
+ if item.query_params:
170
+ item.link += f"?{urlencode(item.query_params)}"
177
171
  except NoReverseMatch as e:
178
172
  # Catch the invalid link here and render the link name as an error message in the template
179
173
  logger.debug("%s", e)
@@ -234,11 +228,6 @@ def register_menu_items(tab_list):
234
228
  )
235
229
 
236
230
 
237
- def register_new_ui_menu_items(context_list):
238
- for nav_context in context_list:
239
- create_or_check_entry(registry["new_ui_nav_menu"], nav_context, nav_context.name, nav_context.name)
240
-
241
-
242
231
  def register_homepage_panels(path, label, homepage_layout):
243
232
  """
244
233
  Register homepage panels using `homepage.py`.
@@ -316,551 +305,6 @@ def register_homepage_panels(path, label, homepage_layout):
316
305
  )
317
306
 
318
307
 
319
- class HomePageBase(ABC):
320
- """Base class for homepage layout classes."""
321
-
322
- @property
323
- @abstractmethod
324
- def initial_dict(self): # to be implemented by each subclass
325
- return {}
326
-
327
- @property
328
- @abstractmethod
329
- def fixed_fields(self): # to be implemented by subclass
330
- return ()
331
-
332
-
333
- class NavMenuBase(ABC): # replaces PermissionsMixin
334
- """Base class for navigation classes."""
335
-
336
- @property
337
- @abstractmethod
338
- def initial_dict(self) -> dict: # to be implemented by each subclass
339
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
340
- return {}
341
-
342
- @property
343
- @abstractmethod
344
- def fixed_fields(self) -> tuple: # to be implemented by subclass
345
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
346
- return ()
347
-
348
-
349
- class PermissionsMixin:
350
- """Ensure permissions through init."""
351
-
352
- def __init__(self, permissions=None):
353
- """Ensure permissions."""
354
- if permissions is not None and not isinstance(permissions, (list, tuple)):
355
- raise TypeError("Permissions must be passed as a tuple or list.")
356
- self.permissions = set(permissions) if permissions else None
357
-
358
-
359
- class HomePagePanel(HomePageBase, PermissionsMixin):
360
- """Defines properties that can be used for a panel."""
361
-
362
- items = None
363
- template_path = None
364
-
365
- @property
366
- def initial_dict(self):
367
- return {
368
- "custom_template": self.custom_template,
369
- "custom_data": self.custom_data,
370
- "weight": self.weight,
371
- "items": {},
372
- "permissions": self.permissions,
373
- "template_path": self.template_path,
374
- }
375
-
376
- @property
377
- def fixed_fields(self):
378
- return ()
379
-
380
- def __init__(self, name, permissions=None, custom_data=None, custom_template=None, items=None, weight=1000):
381
- """
382
- Ensure panel properties.
383
-
384
- Args:
385
- name (str): The name of the panel.
386
- permissions (list): The permissions required to view this panel.
387
- custom_data (dict): Custom data to be passed to the custom template.
388
- custom_template (str): Name of custom template.
389
- items (list): List of items to be rendered in this panel.
390
- weight (int): The weight of this panel.
391
- """
392
- super().__init__(permissions)
393
- self.custom_data = custom_data
394
- self.custom_template = custom_template
395
- self.name = name
396
- self.weight = weight
397
-
398
- if items is not None and custom_template is not None:
399
- raise ValueError("Cannot specify items and custom_template at the same time.")
400
- if items is not None:
401
- if not isinstance(items, (list, tuple)):
402
- raise TypeError("Items must be passed as a tuple or list.")
403
- elif not all(isinstance(item, (HomePageGroup, HomePageItem)) for item in items):
404
- raise TypeError("All items defined in a panel must be an instance of HomePageGroup or HomePageItem")
405
- self.items = items
406
- else:
407
- self.items = []
408
-
409
-
410
- class HomePageGroup(HomePageBase, PermissionsMixin):
411
- """Defines properties that can be used for a panel group."""
412
-
413
- items = []
414
-
415
- @property
416
- def initial_dict(self):
417
- return {
418
- "items": {},
419
- "permissions": self.permissions,
420
- "weight": self.weight,
421
- }
422
-
423
- @property
424
- def fixed_fields(self):
425
- return ()
426
-
427
- def __init__(self, name, permissions=None, items=None, weight=1000):
428
- """
429
- Ensure group properties.
430
-
431
- Args:
432
- name (str): The name of the group.
433
- permissions (list): The permissions required to view this group.
434
- items (list): List of items to be rendered in this group.
435
- weight (int): The weight of this group.
436
- """
437
- super().__init__(permissions)
438
- self.name = name
439
- self.weight = weight
440
-
441
- if items is not None:
442
- if not isinstance(items, (list, tuple)):
443
- raise TypeError("Items must be passed as a tuple or list.")
444
- elif not all(isinstance(item, HomePageItem) for item in items):
445
- raise TypeError("All items defined in a group must be an instance of HomePageItem")
446
- self.items = items
447
-
448
-
449
- class HomePageItem(HomePageBase, PermissionsMixin):
450
- """Defines properties that can be used for a panel item."""
451
-
452
- items = []
453
- template_path = None
454
-
455
- @property
456
- def initial_dict(self):
457
- return {
458
- "custom_template": self.custom_template,
459
- "custom_data": self.custom_data,
460
- "description": self.description,
461
- "link": self.link,
462
- "model": self.model,
463
- "permissions": self.permissions,
464
- "template_path": self.template_path,
465
- "weight": self.weight,
466
- }
467
-
468
- @property
469
- def fixed_fields(self):
470
- return ()
471
-
472
- def __init__(
473
- self,
474
- name,
475
- link=None,
476
- model=None,
477
- custom_template=None,
478
- custom_data=None,
479
- description=None,
480
- permissions=None,
481
- weight=1000,
482
- ):
483
- """
484
- Ensure item properties.
485
-
486
- Args:
487
- name (str): The name of the item.
488
- link (str): The link to be used for this item.
489
- model (str): The model to being used for this item to calculate the total count of objects.
490
- custom_template (str): Name of custom template.
491
- custom_data (dict): Custom data to be passed to the custom template.
492
- """
493
- super().__init__(permissions)
494
-
495
- self.name = name
496
- self.custom_template = custom_template
497
- self.custom_data = custom_data
498
- self.description = description
499
- self.link = link
500
- self.model = model
501
- self.weight = weight
502
-
503
- if model is not None and custom_template is not None:
504
- raise ValueError("Cannot specify model and custom_template at the same time.")
505
-
506
-
507
- class NavMenuTab(NavMenuBase, PermissionsMixin):
508
- """
509
- Ths class represents a navigation menu tab. This is built up from a name and a weight value. The name is
510
- the display text and the weight defines its position in the navbar.
511
-
512
- Groups are each specified as a list of NavMenuGroup instances.
513
- """
514
-
515
- permissions = []
516
- groups = []
517
-
518
- @property
519
- def initial_dict(self) -> dict:
520
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
521
- return {
522
- "weight": self.weight,
523
- "groups": {},
524
- "permissions": set(),
525
- }
526
-
527
- @property
528
- def fixed_fields(self) -> tuple:
529
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
530
- return ()
531
-
532
- def __init__(self, name, permissions=None, groups=None, weight=1000):
533
- """
534
- Ensure tab properties.
535
-
536
- Args:
537
- name (str): The name of the tab.
538
- permissions (list): The permissions required to view this tab.
539
- groups (list): List of groups to be rendered in this tab.
540
- weight (int): The weight of this tab.
541
- """
542
- super().__init__(permissions)
543
- self.name = name
544
- self.weight = weight
545
- if groups is not None:
546
- if not isinstance(groups, (list, tuple)):
547
- raise TypeError("Groups must be passed as a tuple or list.")
548
- elif not all(isinstance(group, NavMenuGroup) for group in groups):
549
- raise TypeError("All groups defined in a tab must be an instance of NavMenuGroup")
550
- self.groups = groups
551
-
552
-
553
- class NavMenuGroup(NavMenuBase, PermissionsMixin):
554
- """
555
- Ths class represents a navigation menu group. This is built up from a name and a weight value. The name is
556
- the display text and the weight defines its position in the navbar.
557
-
558
- Items are each specified as a list of NavMenuItem instances.
559
- """
560
-
561
- permissions = []
562
- items = []
563
-
564
- @property
565
- def initial_dict(self) -> dict:
566
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
567
- return {
568
- "weight": self.weight,
569
- "items": {},
570
- "permissions": set(),
571
- }
572
-
573
- @property
574
- def fixed_fields(self) -> tuple:
575
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
576
- return ()
577
-
578
- def __init__(self, name, items=None, weight=1000):
579
- """
580
- Ensure group properties.
581
-
582
- Args:
583
- name (str): The name of the group.
584
- items (list): List of items to be rendered in this group.
585
- weight (int): The weight of this group.
586
- """
587
- self.name = name
588
- self.weight = weight
589
-
590
- if items is not None and not isinstance(items, (list, tuple)):
591
- raise TypeError("Items must be passed as a tuple or list.")
592
- elif not all(isinstance(item, NavMenuItem) for item in items):
593
- raise TypeError("All items defined in a group must be an instance of NavMenuItem")
594
- self.items = items
595
- super().__init__(permissions=self.permissions)
596
-
597
-
598
- class NavMenuItem(NavMenuBase, PermissionsMixin):
599
- """
600
- This class represents a navigation menu item. This constitutes primary link and its text, but also allows for
601
- specifying additional link buttons that appear to the right of the item in the nav menu.
602
-
603
- Links are specified as Django reverse URL strings.
604
- Buttons are each specified as a list of NavMenuButton instances.
605
- """
606
-
607
- @property
608
- def initial_dict(self) -> dict:
609
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
610
- return {
611
- "name": self.name,
612
- "weight": self.weight,
613
- "buttons": {},
614
- "permissions": self.permissions,
615
- "args": [],
616
- "kwargs": {},
617
- }
618
-
619
- @property
620
- def fixed_fields(self) -> tuple:
621
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
622
- return (
623
- ("name", self.name),
624
- ("permissions", self.permissions),
625
- )
626
-
627
- permissions = []
628
- buttons = []
629
- args = []
630
- kwargs = {}
631
-
632
- def __init__(self, link, name, args=None, kwargs=None, permissions=None, buttons=(), weight=1000):
633
- """
634
- Ensure item properties.
635
-
636
- Args:
637
- link (str): The link to be used for this item.
638
- name (str): The name of the item.
639
- args (list): Arguments that are being passed to the url with reverse() method
640
- kwargs (dict): Keyword arguments are are being passed to the url with reverse() method
641
- permissions (list): The permissions required to view this item.
642
- buttons (list): List of buttons to be rendered in this item.
643
- weight (int): The weight of this item.
644
- """
645
- super().__init__(permissions)
646
- self.link = link
647
- self.name = name
648
- self.weight = weight
649
- self.args = args
650
- self.kwargs = kwargs
651
-
652
- if not isinstance(buttons, (list, tuple)):
653
- raise TypeError("Buttons must be passed as a tuple or list.")
654
- elif not all(isinstance(button, NavMenuButton) for button in buttons):
655
- raise TypeError("All buttons defined in an item must be an instance or subclass of NavMenuButton")
656
- self.buttons = buttons
657
-
658
-
659
- class NavMenuButton(NavMenuBase, PermissionsMixin):
660
- """
661
- This class represents a button within a NavMenuItem.
662
- """
663
-
664
- @property
665
- def initial_dict(self) -> dict:
666
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
667
- return {
668
- "link": self.link,
669
- "icon_class": self.icon_class,
670
- "button_class": self.button_class,
671
- "weight": self.weight,
672
- "buttons": {},
673
- "permissions": self.permissions,
674
- }
675
-
676
- @property
677
- def fixed_fields(self) -> tuple:
678
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
679
- return (
680
- ("button_class", self.button_class),
681
- ("icon_class", self.icon_class),
682
- ("link", self.link),
683
- ("permissions", self.permissions),
684
- )
685
-
686
- def __init__(
687
- self,
688
- link,
689
- title,
690
- icon_class,
691
- button_class=ButtonActionColorChoices.DEFAULT,
692
- permissions=None,
693
- weight=1000,
694
- ):
695
- """
696
- Ensure button properties.
697
-
698
- Args:
699
- link (str): The link to be used for this button.
700
- title (str): The title of the button.
701
- icon_class (str): The icon class to be used as the icon for the start of the button.
702
- button_class (str): The button class defines to be used to define the style of the button.
703
- permissions (list): The permissions required to view this button.
704
- weight (int): The weight of this button.
705
- """
706
- super().__init__(permissions)
707
- self.link = link
708
- self.title = title
709
- self.icon_class = icon_class
710
- self.weight = weight
711
- self.button_class = button_class
712
-
713
-
714
- class NavMenuAddButton(NavMenuButton):
715
- """Add button subclass."""
716
-
717
- def __init__(self, *args, **kwargs):
718
- """Ensure button properties."""
719
- if "title" not in kwargs:
720
- kwargs["title"] = "Add"
721
- if "icon_class" not in kwargs:
722
- kwargs["icon_class"] = ButtonActionIconChoices.ADD
723
- if "button_class" not in kwargs:
724
- kwargs["button_class"] = ButtonActionColorChoices.ADD
725
- if "weight" not in kwargs:
726
- kwargs["weight"] = 100
727
- super().__init__(*args, **kwargs)
728
-
729
-
730
- class NavMenuImportButton(NavMenuButton):
731
- """Import button subclass."""
732
-
733
- def __init__(self, *args, **kwargs):
734
- """Ensure button properties."""
735
- if "title" not in kwargs:
736
- kwargs["title"] = "Import"
737
- if "icon_class" not in kwargs:
738
- kwargs["icon_class"] = ButtonActionIconChoices.IMPORT
739
- if "button_class" not in kwargs:
740
- kwargs["button_class"] = ButtonActionColorChoices.IMPORT
741
- if "weight" not in kwargs:
742
- kwargs["weight"] = 200
743
- super().__init__(*args, **kwargs)
744
-
745
-
746
- class NavContext(NavMenuBase):
747
- """Ths class represents a navigation menu tab for new ui.
748
-
749
- Groups are each specified as a list of NavGrouping instances.
750
- """
751
-
752
- def __init__(self, name, groups, weight=1000):
753
- self.name = name
754
- self.groups = groups
755
- self.weight = weight
756
- self.validate()
757
-
758
- def validate(self):
759
- # NavContext name must belong in this group ("Inventory", "Networks", "Security", "Automation", "Platform")
760
- if self.name not in NAV_CONTEXT_NAMES:
761
- raise TypeError(f"`{self.name}` is an invalid context name, valid choices are: {NAV_CONTEXT_NAMES}")
762
-
763
- if self.groups:
764
- groups = self.groups
765
- if not isinstance(groups, (list, tuple)):
766
- raise TypeError("Groups must be passed as a tuple or list.")
767
- elif not all(isinstance(group, NavGrouping) for group in groups):
768
- raise TypeError("All groups defined in a NavContext must be an instance of NavGrouping")
769
-
770
- @property
771
- def initial_dict(self) -> dict:
772
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
773
- return {
774
- "weight": self.weight,
775
- "data": {},
776
- }
777
-
778
- @property
779
- def fixed_fields(self) -> tuple:
780
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
781
- return ()
782
-
783
-
784
- class NavGrouping(NavMenuBase, PermissionsMixin):
785
- """
786
- Ths class represents a navigation menu group for the new ui. This is built up from a name and a weight value. The name is
787
- the display text and the weight defines its position in the navigation sidebar.
788
-
789
- Items are each specified as a list of NavItem or NavGrouping instances.
790
- """
791
-
792
- def __init__(self, name, items, weight=1000): # pylint:disable=super-init-not-called # this is dead code anyway
793
- self.name = name
794
- self.items = items
795
- self.weight = weight
796
- self.validate()
797
-
798
- def validate(self):
799
- if self.items:
800
- items = self.items
801
- if items is not None and not isinstance(items, (list, tuple)):
802
- raise TypeError("Items must be passed as a tuple or list.")
803
-
804
- if not all(isinstance(item, (NavItem, self.__class__)) for item in items):
805
- raise TypeError("All items defined in a NavGrouping must be an instance of NavItem or NavGrouping")
806
-
807
- @property
808
- def initial_dict(self) -> dict:
809
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
810
- return {
811
- "weight": self.weight,
812
- "data": {},
813
- }
814
-
815
- @property
816
- def fixed_fields(self) -> tuple:
817
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
818
- return ()
819
-
820
-
821
- class NavItem(NavMenuBase, PermissionsMixin):
822
- """
823
- This class represents a navigation menu item for the new ui. This constitutes link and its text.
824
-
825
- Links are specified as Django reverse URL strings.
826
- """
827
-
828
- def __init__( # pylint:disable=super-init-not-called # this is dead code anyway
829
- self, name, link, *args, permissions=None, weight=1000, **kwargs
830
- ):
831
- self.name = name
832
- self.link = link
833
- self.permissions = permissions or []
834
- self.weight = weight
835
- self.args = args
836
- self.kwargs = kwargs
837
-
838
- @property
839
- def initial_dict(self) -> dict:
840
- """Attributes to be stored when adding this item to the nav menu data for the first time."""
841
- return {
842
- "name": self.name,
843
- "weight": self.weight,
844
- "permissions": self.permissions,
845
- "data": self.url(),
846
- }
847
-
848
- @property
849
- def fixed_fields(self):
850
- """Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
851
- return (
852
- ("name", self.name),
853
- ("permissions", self.permissions),
854
- )
855
-
856
- def url(self):
857
- try:
858
- return reverse(self.link, args=self.args, kwargs=self.kwargs)
859
- except NoReverseMatch as e:
860
- logger.error("Error in link construction for %s: %s", self.name, e)
861
- return ""
862
-
863
-
864
308
  def post_migrate_send_nautobot_database_ready(sender, app_config, signal, **kwargs):
865
309
  """
866
310
  Send the `nautobot_database_ready` signal to all installed core apps and Apps.
@@ -14,6 +14,7 @@ from django.utils.module_loading import import_string
14
14
  from kombu.serialization import register
15
15
  from prometheus_client import CollectorRegistry, multiprocess, start_http_server
16
16
 
17
+ from nautobot import add_success_logger
17
18
  from nautobot.core.celery.control import discard_git_repository, refresh_git_repository # noqa: F401 # unused-import
18
19
  from nautobot.core.celery.encoders import NautobotKombuJSONEncoder
19
20
  from nautobot.core.celery.log import NautobotDatabaseHandler
@@ -135,6 +136,18 @@ def add_nautobot_log_handler(logger_instance, log_format=None):
135
136
  logger_instance.addHandler(handler)
136
137
 
137
138
 
139
+ @signals.after_setup_logger.connect
140
+ def setup_nautobot_global_logging(logger, **kwargs): # pylint: disable=redefined-outer-name
141
+ """Add SUCCESS log to celery global logger."""
142
+ logger.success = add_success_logger()
143
+
144
+
145
+ @signals.after_setup_task_logger.connect
146
+ def setup_nautobot_task_logging(logger, **kwargs): # pylint: disable=redefined-outer-name
147
+ """Add SUCCESS log to celery task logger."""
148
+ logger.success = add_success_logger()
149
+
150
+
138
151
  @signals.celeryd_after_setup.connect
139
152
  def setup_nautobot_job_logging(sender, instance, conf, **kwargs):
140
153
  """Add nautobot database logging handler to celery stdout/stderr redirect logger and celery task logger."""
@@ -11,10 +11,6 @@ class NautobotDatabaseHandler(logging.Handler):
11
11
  if current_task is None:
12
12
  return
13
13
 
14
- # Skip recording the log entry if it has been marked as such
15
- if getattr(record, "skip_db_logging", False):
16
- return
17
-
18
14
  from nautobot.extras.models.jobs import JobResult
19
15
 
20
16
  try:
@@ -28,6 +24,10 @@ class NautobotDatabaseHandler(logging.Handler):
28
24
  # JobResult.DoesNotExist - because we might not have a JobResult with that ID
29
25
  return
30
26
 
27
+ # Skip recording the log entry if it has been marked as such
28
+ if getattr(record, "skip_db_logging", False):
29
+ return
30
+
31
31
  job_result.log(
32
32
  message=record.message,
33
33
  level_choice=record.levelname.lower(),