nautobot 2.1.0b1__py3-none-any.whl → 2.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1002) hide show
  1. nautobot/__init__.py +1 -3
  2. nautobot/apps/__init__.py +1 -2
  3. nautobot/apps/admin.py +0 -1
  4. nautobot/apps/api.py +0 -1
  5. nautobot/apps/change_logging.py +0 -1
  6. nautobot/apps/choices.py +0 -3
  7. nautobot/apps/datasources.py +2 -2
  8. nautobot/apps/exceptions.py +0 -1
  9. nautobot/apps/factory.py +0 -1
  10. nautobot/apps/filters.py +6 -9
  11. nautobot/apps/forms.py +1 -2
  12. nautobot/apps/graphql.py +0 -1
  13. nautobot/apps/jobs.py +2 -1
  14. nautobot/apps/models.py +4 -2
  15. nautobot/apps/querysets.py +0 -1
  16. nautobot/apps/secrets.py +0 -1
  17. nautobot/apps/tables.py +0 -1
  18. nautobot/apps/testing.py +0 -1
  19. nautobot/apps/ui.py +1 -3
  20. nautobot/apps/urls.py +0 -1
  21. nautobot/apps/utils.py +0 -1
  22. nautobot/apps/views.py +0 -1
  23. nautobot/circuits/api/serializers.py +1 -1
  24. nautobot/circuits/api/urls.py +1 -1
  25. nautobot/circuits/api/views.py +2 -1
  26. nautobot/circuits/apps.py +1 -1
  27. nautobot/circuits/choices.py +0 -1
  28. nautobot/circuits/factory.py +1 -1
  29. nautobot/circuits/filters.py +2 -1
  30. nautobot/circuits/forms.py +2 -2
  31. nautobot/circuits/homepage.py +0 -1
  32. nautobot/circuits/migrations/0001_initial_part_1.py +3 -1
  33. nautobot/circuits/migrations/0002_initial_part_2.py +2 -1
  34. nautobot/circuits/migrations/0003_auto_slug.py +1 -0
  35. nautobot/circuits/migrations/0005_providernetwork.py +4 -2
  36. nautobot/circuits/migrations/0013_alter_circuittermination__path.py +1 -0
  37. nautobot/circuits/migrations/0014_related_name_changes.py +1 -0
  38. nautobot/circuits/migrations/0016_tagsfield.py +1 -0
  39. nautobot/circuits/migrations/0018_status_nonnullable.py +1 -0
  40. nautobot/circuits/models.py +2 -2
  41. nautobot/circuits/navigation.py +0 -1
  42. nautobot/circuits/signals.py +3 -2
  43. nautobot/circuits/tables.py +1 -0
  44. nautobot/circuits/tests/integration/test_relationships.py +1 -1
  45. nautobot/circuits/tests/test_api.py +1 -1
  46. nautobot/circuits/tests/test_urls.py +1 -1
  47. nautobot/circuits/tests/test_views.py +1 -0
  48. nautobot/circuits/urls.py +1 -1
  49. nautobot/circuits/views.py +1 -10
  50. nautobot/core/__init__.py +0 -1
  51. nautobot/core/admin.py +3 -5
  52. nautobot/core/api/__init__.py +0 -1
  53. nautobot/core/api/metadata.py +4 -6
  54. nautobot/core/api/pagination.py +2 -2
  55. nautobot/core/api/parsers.py +1 -3
  56. nautobot/core/api/renderers.py +0 -1
  57. nautobot/core/api/schema.py +2 -3
  58. nautobot/core/api/serializers.py +9 -7
  59. nautobot/core/api/urls.py +1 -5
  60. nautobot/core/api/utils.py +14 -15
  61. nautobot/core/api/versioning.py +1 -1
  62. nautobot/core/api/views.py +22 -91
  63. nautobot/core/apps/__init__.py +5 -7
  64. nautobot/core/authentication.py +1 -1
  65. nautobot/core/celery/__init__.py +1 -2
  66. nautobot/core/celery/control.py +0 -2
  67. nautobot/core/celery/encoders.py +0 -1
  68. nautobot/core/celery/schedulers.py +1 -2
  69. nautobot/core/celery/task.py +1 -1
  70. nautobot/core/checks.py +31 -2
  71. nautobot/core/choices.py +2 -2
  72. nautobot/core/cli/__init__.py +8 -17
  73. nautobot/core/context_processors.py +1 -5
  74. nautobot/core/factory.py +2 -2
  75. nautobot/core/filters.py +1 -1
  76. nautobot/core/forms/fields.py +2 -4
  77. nautobot/core/forms/forms.py +1 -1
  78. nautobot/core/forms/search.py +1 -1
  79. nautobot/core/forms/utils.py +1 -1
  80. nautobot/core/graphql/__init__.py +2 -3
  81. nautobot/core/graphql/generators.py +2 -2
  82. nautobot/core/graphql/schema.py +21 -8
  83. nautobot/core/graphql/schema_init.py +0 -1
  84. nautobot/core/graphql/types.py +10 -0
  85. nautobot/core/graphql/utils.py +1 -2
  86. nautobot/core/management/commands/generate_test_data.py +7 -6
  87. nautobot/core/management/commands/makemigrations.py +1 -1
  88. nautobot/core/management/commands/migrate.py +1 -1
  89. nautobot/core/management/commands/post_upgrade.py +1 -15
  90. nautobot/core/management/commands/refresh_content_type_cache.py +1 -2
  91. nautobot/core/management/commands/send_installation_metrics.py +2 -3
  92. nautobot/core/management/commands/validate_models.py +1 -1
  93. nautobot/core/middleware.py +2 -2
  94. nautobot/core/models/__init__.py +12 -12
  95. nautobot/core/models/fields.py +1 -1
  96. nautobot/core/models/generics.py +2 -3
  97. nautobot/core/models/managers.py +0 -1
  98. nautobot/core/models/name_color_content_types.py +2 -2
  99. nautobot/core/models/tree_queries.py +2 -4
  100. nautobot/core/models/validators.py +1 -1
  101. nautobot/core/releases.py +1 -1
  102. nautobot/core/runner/importer.py +2 -25
  103. nautobot/core/runner/runner.py +2 -2
  104. nautobot/core/runner/settings.py +1 -1
  105. nautobot/core/settings.py +15 -21
  106. nautobot/core/settings_funcs.py +1 -2
  107. nautobot/core/signals.py +0 -1
  108. nautobot/core/tables.py +1 -1
  109. nautobot/core/templates/admin/base.html +9 -9
  110. nautobot/core/templates/exceptions/programming_error.html +2 -2
  111. nautobot/core/templates/graphene/graphiql.html +9 -3
  112. nautobot/core/templates/home.html +26 -6
  113. nautobot/core/templates/inc/footer.html +0 -7
  114. nautobot/core/templates/inc/javascript.html +4 -2
  115. nautobot/core/templates/inc/media.html +2 -2
  116. nautobot/core/templates/inc/nav_menu.html +27 -25
  117. nautobot/core/templates/inc/object_details_advanced_panel.html +12 -0
  118. nautobot/core/templates/nautobot_config.py.j2 +4 -4
  119. nautobot/core/templates/utilities/theme_preview.html +883 -0
  120. nautobot/core/templatetags/bootstrapped_goodies_tags.py +6 -3
  121. nautobot/core/templatetags/buttons.py +2 -1
  122. nautobot/core/templatetags/helpers.py +45 -18
  123. nautobot/core/testing/__init__.py +1 -2
  124. nautobot/core/testing/api.py +2 -4
  125. nautobot/core/testing/filters.py +1 -1
  126. nautobot/core/testing/integration.py +2 -2
  127. nautobot/core/testing/migrations.py +1 -0
  128. nautobot/core/testing/mixins.py +1 -2
  129. nautobot/core/testing/schema.py +1 -1
  130. nautobot/core/testing/utils.py +3 -3
  131. nautobot/core/testing/views.py +8 -8
  132. nautobot/core/tests/integration/test_home.py +1 -1
  133. nautobot/core/tests/integration/test_navbar.py +2 -2
  134. nautobot/core/tests/integration/test_plugin_home.py +2 -1
  135. nautobot/core/tests/integration/test_plugin_navbar.py +6 -6
  136. nautobot/core/tests/nautobot_config.py +3 -3
  137. nautobot/core/tests/runner.py +3 -4
  138. nautobot/core/tests/test_api.py +6 -51
  139. nautobot/core/tests/test_authentication.py +2 -3
  140. nautobot/core/tests/test_checks.py +1 -2
  141. nautobot/core/tests/test_config.py +1 -1
  142. nautobot/core/tests/test_csv.py +4 -4
  143. nautobot/core/tests/test_factory.py +1 -3
  144. nautobot/core/tests/test_filters.py +4 -7
  145. nautobot/core/tests/test_forms.py +3 -6
  146. nautobot/core/tests/test_graphql.py +33 -17
  147. nautobot/core/tests/test_jinja_filters.py +5 -4
  148. nautobot/core/tests/test_jobs.py +1 -1
  149. nautobot/core/tests/test_models.py +28 -3
  150. nautobot/core/tests/test_navigations.py +2 -1
  151. nautobot/core/tests/test_openapi.py +0 -1
  152. nautobot/core/tests/test_paginator.py +2 -2
  153. nautobot/core/tests/test_releases.py +2 -2
  154. nautobot/core/tests/test_tables.py +1 -1
  155. nautobot/core/tests/test_templatetags_helpers.py +17 -2
  156. nautobot/core/tests/test_templatetags_netutils.py +1 -2
  157. nautobot/core/tests/test_utils.py +4 -8
  158. nautobot/core/tests/test_views.py +95 -1
  159. nautobot/core/tests/test_views_utils.py +0 -1
  160. nautobot/core/urls.py +24 -4
  161. nautobot/core/utils/color.py +1 -1
  162. nautobot/core/utils/data.py +1 -2
  163. nautobot/core/utils/filtering.py +4 -5
  164. nautobot/core/utils/git.py +6 -2
  165. nautobot/core/utils/logging.py +2 -1
  166. nautobot/core/utils/lookup.py +4 -6
  167. nautobot/core/utils/migrations.py +1 -0
  168. nautobot/core/utils/permissions.py +2 -4
  169. nautobot/core/utils/requests.py +10 -0
  170. nautobot/core/views/__init__.py +32 -8
  171. nautobot/core/views/generic.py +14 -13
  172. nautobot/core/views/mixins.py +24 -22
  173. nautobot/core/views/renderers.py +1 -1
  174. nautobot/core/views/routers.py +6 -0
  175. nautobot/core/views/utils.py +2 -1
  176. nautobot/dcim/api/urls.py +1 -1
  177. nautobot/dcim/api/views.py +6 -5
  178. nautobot/dcim/apps.py +1 -1
  179. nautobot/dcim/choices.py +4 -1
  180. nautobot/dcim/constants.py +0 -1
  181. nautobot/dcim/elevations.py +1 -2
  182. nautobot/dcim/factory.py +125 -13
  183. nautobot/dcim/fields.py +1 -0
  184. nautobot/dcim/filters/__init__.py +2 -3
  185. nautobot/dcim/filters/mixins.py +1 -1
  186. nautobot/dcim/forms.py +37 -44
  187. nautobot/dcim/graphql/types.py +16 -17
  188. nautobot/dcim/migrations/0001_initial_part_1.py +4 -2
  189. nautobot/dcim/migrations/0002_initial_part_2.py +2 -1
  190. nautobot/dcim/migrations/0003_initial_part_3.py +2 -1
  191. nautobot/dcim/migrations/0004_initial_part_4.py +2 -1
  192. nautobot/dcim/migrations/0006_auto_slug.py +1 -0
  193. nautobot/dcim/migrations/0009_add_natural_indexing.py +1 -0
  194. nautobot/dcim/migrations/0010_interface_status.py +1 -0
  195. nautobot/dcim/migrations/0011_interface_status_data_migration.py +1 -0
  196. nautobot/dcim/migrations/0013_location_location_type.py +4 -2
  197. nautobot/dcim/migrations/0014_location_status_data_migration.py +1 -0
  198. nautobot/dcim/migrations/0016_device_components__timestamp_data_migration.py +0 -1
  199. nautobot/dcim/migrations/0018_device_redundancy_group.py +4 -2
  200. nautobot/dcim/migrations/0019_device_redundancy_group_data_migration.py +1 -0
  201. nautobot/dcim/migrations/0022_interface_redundancy_group.py +3 -1
  202. nautobot/dcim/migrations/0023_interface_redundancy_group_data_migration.py +1 -0
  203. nautobot/dcim/migrations/0024_move_site_fields_to_location_model.py +2 -1
  204. nautobot/dcim/migrations/0027_alter_interface_mac_address.py +1 -0
  205. nautobot/dcim/migrations/0028_alter_device_and_rack_role_add_new_role.py +1 -0
  206. nautobot/dcim/migrations/0029_device_and_rack_roles_data_migrations.py +1 -0
  207. nautobot/dcim/migrations/0033_add_tree_managers_and_foreign_keys_pre_data_migration.py +1 -0
  208. nautobot/dcim/migrations/0034_migrate_region_and_site_data_to_locations.py +1 -2
  209. nautobot/dcim/migrations/0038_fixup_fks_and_related_names.py +1 -0
  210. nautobot/dcim/migrations/0039_related_name_changes.py +1 -0
  211. nautobot/dcim/migrations/0042_alter_location_managers.py +1 -0
  212. nautobot/dcim/migrations/0044_tagsfield.py +1 -0
  213. nautobot/dcim/migrations/0047_status_nonnullable.py +1 -0
  214. nautobot/dcim/migrations/0051_interface_redundancy_group_nullable_status.py +1 -0
  215. nautobot/dcim/models/cables.py +3 -3
  216. nautobot/dcim/models/device_component_templates.py +6 -6
  217. nautobot/dcim/models/devices.py +9 -4
  218. nautobot/dcim/models/locations.py +6 -1
  219. nautobot/dcim/models/power.py +1 -1
  220. nautobot/dcim/models/racks.py +5 -4
  221. nautobot/dcim/navigation.py +0 -1
  222. nautobot/dcim/signals.py +3 -2
  223. nautobot/dcim/tables/__init__.py +5 -4
  224. nautobot/dcim/tables/cables.py +1 -0
  225. nautobot/dcim/tables/devices.py +1 -0
  226. nautobot/dcim/tables/locations.py +1 -1
  227. nautobot/dcim/tables/power.py +1 -0
  228. nautobot/dcim/tables/racks.py +2 -1
  229. nautobot/dcim/templates/dcim/device/consoleports.html +2 -2
  230. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -2
  231. nautobot/dcim/templates/dcim/device/devicebays.html +1 -1
  232. nautobot/dcim/templates/dcim/device/frontports.html +2 -2
  233. nautobot/dcim/templates/dcim/device/interfaces.html +4 -4
  234. nautobot/dcim/templates/dcim/device/inventory.html +1 -1
  235. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -2
  236. nautobot/dcim/templates/dcim/device/powerports.html +2 -2
  237. nautobot/dcim/templates/dcim/device/rearports.html +2 -2
  238. nautobot/dcim/templates/dcim/inc/location_hierarchy.html +4 -2
  239. nautobot/dcim/templates/dcim/rack.html +1 -1
  240. nautobot/dcim/templates/dcim/rack_elevation_list.html +1 -1
  241. nautobot/dcim/templates/dcim/rackreservation.html +1 -1
  242. nautobot/dcim/tests/test_api.py +7 -7
  243. nautobot/dcim/tests/test_cablepaths.py +0 -1
  244. nautobot/dcim/tests/test_filters.py +16 -13
  245. nautobot/dcim/tests/test_forms.py +2 -3
  246. nautobot/dcim/tests/test_graphql.py +1 -0
  247. nautobot/dcim/tests/test_migrations.py +2 -2
  248. nautobot/dcim/tests/test_models.py +2 -2
  249. nautobot/dcim/tests/test_views.py +77 -14
  250. nautobot/dcim/urls.py +3 -2
  251. nautobot/dcim/utils.py +1 -1
  252. nautobot/dcim/views.py +4 -3
  253. nautobot/extras/admin.py +2 -1
  254. nautobot/extras/api/customfields.py +0 -2
  255. nautobot/extras/api/mixins.py +0 -1
  256. nautobot/extras/api/serializers.py +4 -4
  257. nautobot/extras/api/urls.py +1 -1
  258. nautobot/extras/api/views.py +1 -1
  259. nautobot/extras/apps.py +3 -4
  260. nautobot/extras/choices.py +3 -18
  261. nautobot/extras/context_managers.py +1 -1
  262. nautobot/extras/datasources/__init__.py +3 -1
  263. nautobot/extras/datasources/git.py +33 -12
  264. nautobot/extras/datasources/utils.py +0 -1
  265. nautobot/extras/factory.py +20 -0
  266. nautobot/extras/filters/__init__.py +2 -3
  267. nautobot/extras/filters/customfields.py +0 -1
  268. nautobot/extras/filters/mixins.py +1 -1
  269. nautobot/extras/forms/__init__.py +3 -4
  270. nautobot/extras/forms/base.py +1 -1
  271. nautobot/extras/forms/forms.py +29 -11
  272. nautobot/extras/forms/mixins.py +1 -1
  273. nautobot/extras/graphql/types.py +2 -2
  274. nautobot/extras/health_checks.py +1 -1
  275. nautobot/extras/jobs.py +43 -25
  276. nautobot/extras/management/__init__.py +0 -1
  277. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -1
  278. nautobot/extras/management/commands/runjob.py +3 -3
  279. nautobot/extras/management/commands/webhook_receiver.py +1 -2
  280. nautobot/extras/migrations/0001_initial_part_1.py +2 -1
  281. nautobot/extras/migrations/0002_initial_part_2.py +2 -1
  282. nautobot/extras/migrations/0003_initial_part_3.py +1 -0
  283. nautobot/extras/migrations/0006_graphqlquery.py +2 -1
  284. nautobot/extras/migrations/0007_configcontextschema.py +3 -1
  285. nautobot/extras/migrations/0009_computedfield.py +3 -1
  286. nautobot/extras/migrations/0011_fileattachment_fileproxy.py +3 -1
  287. nautobot/extras/migrations/0012_healthchecktestmodel.py +2 -1
  288. nautobot/extras/migrations/0014_auto_slug.py +1 -0
  289. nautobot/extras/migrations/0015_scheduled_job.py +3 -1
  290. nautobot/extras/migrations/0016_secret.py +4 -2
  291. nautobot/extras/migrations/0017_joblogentry.py +2 -1
  292. nautobot/extras/migrations/0018_joblog_data_migration.py +2 -1
  293. nautobot/extras/migrations/0021_customfield_changelog_data.py +3 -2
  294. nautobot/extras/migrations/0022_objectchange_object_datav2.py +1 -0
  295. nautobot/extras/migrations/0023_job_model.py +4 -2
  296. nautobot/extras/migrations/0026_job_add_gitrepository_fk.py +1 -0
  297. nautobot/extras/migrations/0029_dynamicgroup.py +3 -1
  298. nautobot/extras/migrations/0031_tag_content_types.py +1 -0
  299. nautobot/extras/migrations/0032_tag_content_types_data_migration.py +1 -0
  300. nautobot/extras/migrations/0040_dynamicgroup__dynamicgroupmembership.py +2 -1
  301. nautobot/extras/migrations/0041_jobresult_job_kwargs.py +1 -0
  302. nautobot/extras/migrations/0043_note.py +3 -1
  303. nautobot/extras/migrations/0044_add_job_hook.py +3 -1
  304. nautobot/extras/migrations/0046_populate_custom_field_slug_label.py +1 -0
  305. nautobot/extras/migrations/0047_enforce_custom_field_slug.py +1 -0
  306. nautobot/extras/migrations/0051_add_job_task_queues.py +1 -0
  307. nautobot/extras/migrations/0055_configcontext_dynamic_groups.py +1 -0
  308. nautobot/extras/migrations/0057_jobbutton.py +3 -1
  309. nautobot/extras/migrations/0065_configcontext_data_migrations.py +1 -0
  310. nautobot/extras/migrations/0067_migrate_job_result_status.py +0 -1
  311. nautobot/extras/migrations/0068_jobresult__add_celery_fields.py +1 -0
  312. nautobot/extras/migrations/0071_replace_related_names.py +1 -0
  313. nautobot/extras/migrations/0077_migrate_custom_field_data.py +1 -0
  314. nautobot/extras/migrations/0078_remove_name_field_and_make_label_field_non_nullable.py +1 -0
  315. nautobot/extras/migrations/0080_tagsfield.py +1 -0
  316. nautobot/extras/migrations/0082_rename_relationship_name_to_label.py +1 -0
  317. nautobot/extras/migrations/0083_ensure_relationship_keys_are_unique.py +1 -0
  318. nautobot/extras/migrations/0090_joblogentry__log_level_data_migration.py +0 -1
  319. nautobot/extras/migrations/0095_ensure_note_timestamps_are_unique.py +4 -5
  320. nautobot/extras/migrations/0097_alter_job_result_remove_result.py +1 -0
  321. nautobot/extras/migrations/0100_fileproxy_job_result.py +1 -0
  322. nautobot/extras/migrations/0101_externalintegration.py +9 -1
  323. nautobot/extras/models/__init__.py +2 -3
  324. nautobot/extras/models/change_logging.py +0 -1
  325. nautobot/extras/models/customfields.py +13 -4
  326. nautobot/extras/models/datasources.py +2 -2
  327. nautobot/extras/models/groups.py +3 -4
  328. nautobot/extras/models/jobs.py +13 -7
  329. nautobot/extras/models/models.py +61 -24
  330. nautobot/extras/models/relationships.py +8 -4
  331. nautobot/extras/models/roles.py +1 -1
  332. nautobot/extras/models/secrets.py +1 -3
  333. nautobot/extras/models/tags.py +0 -1
  334. nautobot/extras/navigation.py +0 -1
  335. nautobot/extras/plugins/__init__.py +6 -7
  336. nautobot/extras/plugins/tables.py +1 -2
  337. nautobot/extras/plugins/utils.py +1 -1
  338. nautobot/extras/plugins/views.py +21 -21
  339. nautobot/extras/querysets.py +30 -13
  340. nautobot/extras/signals.py +6 -7
  341. nautobot/extras/tables.py +13 -5
  342. nautobot/extras/tasks.py +1 -2
  343. nautobot/extras/templates/extras/configcontext_edit.html +1 -1
  344. nautobot/extras/templates/extras/customfield_edit.html +7 -12
  345. nautobot/extras/templates/extras/dynamicgroup_edit.html +42 -47
  346. nautobot/extras/templates/extras/externalintegration_retrieve.html +12 -0
  347. nautobot/extras/templates/extras/externalintegration_update.html +28 -0
  348. nautobot/extras/templates/extras/gitrepository_result.html +2 -2
  349. nautobot/extras/templates/extras/graphqlquery.html +4 -2
  350. nautobot/extras/templates/extras/inc/jobresult_js.html +1 -1
  351. nautobot/extras/templates/extras/job_list.html +1 -1
  352. nautobot/extras/templates/extras/jobresult.html +2 -2
  353. nautobot/extras/templates/extras/secretsgroup_edit.html +40 -45
  354. nautobot/extras/templatetags/custom_links.py +2 -3
  355. nautobot/extras/templatetags/job_buttons.py +76 -83
  356. nautobot/extras/templatetags/log_levels.py +0 -1
  357. nautobot/extras/templatetags/plugins.py +1 -1
  358. nautobot/extras/test_jobs/api_test_job.py +1 -2
  359. nautobot/extras/test_jobs/atomic_transaction.py +1 -2
  360. nautobot/extras/test_jobs/dry_run.py +1 -2
  361. nautobot/extras/test_jobs/fail.py +1 -2
  362. nautobot/extras/test_jobs/field_order.py +1 -1
  363. nautobot/extras/test_jobs/file_upload_fail.py +1 -2
  364. nautobot/extras/test_jobs/file_upload_pass.py +1 -2
  365. nautobot/extras/test_jobs/has_sensitive_variables.py +1 -2
  366. nautobot/extras/test_jobs/ipaddress_vars.py +1 -4
  367. nautobot/extras/test_jobs/job_button_receiver.py +1 -2
  368. nautobot/extras/test_jobs/job_hook_receiver.py +1 -2
  369. nautobot/extras/test_jobs/job_variables.py +7 -2
  370. nautobot/extras/test_jobs/location_with_custom_field.py +1 -2
  371. nautobot/extras/test_jobs/log_redaction.py +1 -2
  372. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -2
  373. nautobot/extras/test_jobs/modify_db.py +1 -2
  374. nautobot/extras/test_jobs/object_var_optional.py +1 -2
  375. nautobot/extras/test_jobs/object_var_required.py +1 -2
  376. nautobot/extras/test_jobs/object_vars.py +1 -2
  377. nautobot/extras/test_jobs/pass.py +1 -2
  378. nautobot/extras/test_jobs/profiling.py +1 -2
  379. nautobot/extras/tests/integration/__init__.py +1 -1
  380. nautobot/extras/tests/integration/test_computedfields.py +2 -2
  381. nautobot/extras/tests/integration/test_configcontextschema.py +5 -5
  382. nautobot/extras/tests/integration/test_plugins.py +5 -4
  383. nautobot/extras/tests/integration/test_tagfilter.py +1 -1
  384. nautobot/extras/tests/test_api.py +15 -9
  385. nautobot/extras/tests/test_changelog.py +3 -2
  386. nautobot/extras/tests/test_context_managers.py +6 -3
  387. nautobot/extras/tests/test_customfields.py +4 -4
  388. nautobot/extras/tests/test_datasources.py +1 -1
  389. nautobot/extras/tests/test_dynamicgroups.py +3 -3
  390. nautobot/extras/tests/test_filters.py +3 -2
  391. nautobot/extras/tests/test_forms.py +5 -6
  392. nautobot/extras/tests/test_git.py +1 -1
  393. nautobot/extras/tests/test_job_variables.py +20 -1
  394. nautobot/extras/tests/test_jobs.py +34 -5
  395. nautobot/extras/tests/test_models.py +156 -6
  396. nautobot/extras/tests/test_notes.py +0 -1
  397. nautobot/extras/tests/test_plugins.py +71 -9
  398. nautobot/extras/tests/test_relationships.py +3 -3
  399. nautobot/extras/tests/test_tags.py +1 -1
  400. nautobot/extras/tests/test_views.py +105 -25
  401. nautobot/extras/tests/test_webhooks.py +4 -5
  402. nautobot/extras/urls.py +0 -2
  403. nautobot/extras/utils.py +11 -9
  404. nautobot/extras/views.py +42 -44
  405. nautobot/generate_secret_key.py +10 -5
  406. nautobot/ipam/api/serializers.py +1 -2
  407. nautobot/ipam/api/urls.py +1 -1
  408. nautobot/ipam/api/views.py +1 -0
  409. nautobot/ipam/apps.py +2 -1
  410. nautobot/ipam/factory.py +6 -9
  411. nautobot/ipam/fields.py +1 -1
  412. nautobot/ipam/filters.py +42 -58
  413. nautobot/ipam/formfields.py +1 -2
  414. nautobot/ipam/forms.py +5 -4
  415. nautobot/ipam/graphql/types.py +1 -1
  416. nautobot/ipam/homepage.py +0 -1
  417. nautobot/ipam/lookups.py +2 -3
  418. nautobot/ipam/migrations/0002_initial_part_2.py +2 -1
  419. nautobot/ipam/migrations/0003_remove_max_length.py +1 -0
  420. nautobot/ipam/migrations/0004_fixup_p2p_broadcast.py +0 -1
  421. nautobot/ipam/migrations/0005_auto_slug.py +1 -0
  422. nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -0
  423. nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +1 -0
  424. nautobot/ipam/migrations/0020_related_name_changes.py +1 -0
  425. nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +1 -2
  426. nautobot/ipam/migrations/0024_interface_to_ipaddress_m2m.py +2 -1
  427. nautobot/ipam/migrations/0025_interface_ipaddress_m2m_data_migration.py +15 -13
  428. nautobot/ipam/migrations/0028_tagsfield.py +1 -0
  429. nautobot/ipam/migrations/0030_ipam__namespaces.py +3 -1
  430. nautobot/ipam/migrations/0034_status_nonnullable.py +1 -0
  431. nautobot/ipam/migrations/0037_data_migration_vlan_group_name_uniqueness.py +0 -1
  432. nautobot/ipam/migrations/0039_alter_ipaddresstointerface_ip_address.py +20 -0
  433. nautobot/ipam/models.py +11 -8
  434. nautobot/ipam/navigation.py +0 -1
  435. nautobot/ipam/querysets.py +48 -49
  436. nautobot/ipam/tables.py +11 -2
  437. nautobot/ipam/templates/ipam/ipaddress.html +30 -6
  438. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +3 -3
  439. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +32 -0
  440. nautobot/ipam/tests/test_api.py +2 -2
  441. nautobot/ipam/tests/test_filters.py +13 -17
  442. nautobot/ipam/tests/test_migrations.py +1 -2
  443. nautobot/ipam/tests/test_models.py +17 -2
  444. nautobot/ipam/tests/test_ordering.py +1 -1
  445. nautobot/ipam/tests/test_querysets.py +2 -2
  446. nautobot/ipam/tests/test_views.py +6 -6
  447. nautobot/ipam/urls.py +6 -0
  448. nautobot/ipam/utils/migrations.py +0 -1
  449. nautobot/ipam/views.py +26 -6
  450. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +142 -142
  451. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  452. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
  453. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  454. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +307 -307
  455. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  456. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  457. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  458. nautobot/project-static/css/base.css +59 -30
  459. nautobot/project-static/css/dark.css +38 -31
  460. nautobot/project-static/docs/404.html +17 -87
  461. nautobot/project-static/docs/apps/index.html +17 -87
  462. nautobot/project-static/docs/apps/nautobot-apps.html +17 -87
  463. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +405 -475
  464. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +28 -98
  465. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2334 -2396
  466. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +17 -87
  467. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +132 -202
  468. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +17 -87
  469. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +155 -87
  470. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +17 -87
  471. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +17 -87
  472. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +42 -112
  473. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1028 -1098
  474. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +186 -256
  475. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +1454 -1156
  476. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1443 -1507
  477. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +157 -203
  478. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +17 -87
  479. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +32 -102
  480. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3822 -3888
  481. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +990 -1060
  482. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +65 -123
  483. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +1431 -1495
  484. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3618 -3640
  485. nautobot/project-static/docs/development/apps/api/configuration-view.html +17 -87
  486. nautobot/project-static/docs/development/apps/api/database-backend-config.html +19 -89
  487. nautobot/project-static/docs/development/apps/api/models/django-admin.html +17 -87
  488. nautobot/project-static/docs/development/apps/api/models/global-search.html +17 -87
  489. nautobot/project-static/docs/development/apps/api/models/graphql.html +17 -87
  490. nautobot/project-static/docs/development/apps/api/models/index.html +17 -87
  491. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +17 -87
  492. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +17 -87
  493. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +19 -89
  494. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +19 -89
  495. nautobot/project-static/docs/development/apps/api/platform-features/index.html +19 -89
  496. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +17 -87
  497. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +17 -87
  498. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +21 -87
  499. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +17 -87
  500. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +17 -87
  501. nautobot/project-static/docs/development/apps/api/prometheus.html +17 -87
  502. nautobot/project-static/docs/development/apps/api/setup.html +17 -87
  503. nautobot/project-static/docs/development/apps/api/testing.html +20 -90
  504. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +17 -87
  505. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +17 -87
  506. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +17 -87
  507. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +19 -89
  508. nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +209 -140
  509. nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +13 -5390
  510. nautobot/project-static/docs/development/apps/api/views/base-template.html +17 -87
  511. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +22 -92
  512. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +17 -87
  513. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +17 -87
  514. nautobot/project-static/docs/development/apps/api/views/index.html +17 -87
  515. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +17 -87
  516. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +17 -87
  517. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +17 -87
  518. nautobot/project-static/docs/development/apps/api/views/notes.html +19 -89
  519. nautobot/project-static/docs/development/apps/api/views/rest-api.html +17 -87
  520. nautobot/project-static/docs/development/apps/api/views/urls.html +17 -87
  521. nautobot/project-static/docs/development/apps/api/views/view-overrides.html +13 -5385
  522. nautobot/project-static/docs/development/apps/index.html +17 -87
  523. nautobot/project-static/docs/development/apps/migration/code-updates.html +17 -87
  524. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +17 -87
  525. nautobot/project-static/docs/development/apps/migration/from-v1.html +17 -88
  526. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +17 -87
  527. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +17 -87
  528. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +17 -87
  529. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +17 -87
  530. nautobot/project-static/docs/development/apps/porting-from-netbox.html +17 -87
  531. nautobot/project-static/docs/development/core/application-registry.html +20 -90
  532. nautobot/project-static/docs/development/core/best-practices.html +20 -90
  533. nautobot/project-static/docs/development/core/bootstrap-ui.html +5360 -0
  534. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +17 -87
  535. nautobot/project-static/docs/development/core/extending-models.html +21 -87
  536. nautobot/project-static/docs/development/core/generic-views.html +17 -87
  537. nautobot/project-static/docs/development/core/getting-started.html +124 -301
  538. nautobot/project-static/docs/development/core/homepage.html +17 -87
  539. nautobot/project-static/docs/development/core/index.html +17 -87
  540. nautobot/project-static/docs/development/core/model-features.html +17 -87
  541. nautobot/project-static/docs/development/core/natural-keys.html +17 -87
  542. nautobot/project-static/docs/development/core/navigation-menu.html +17 -87
  543. nautobot/project-static/docs/development/core/react-ui.html +13 -5668
  544. nautobot/project-static/docs/development/core/release-checklist.html +20 -96
  545. nautobot/project-static/docs/development/core/role-internals.html +20 -90
  546. nautobot/project-static/docs/development/core/style-guide.html +77 -146
  547. nautobot/project-static/docs/development/core/templates.html +20 -90
  548. nautobot/project-static/docs/development/core/testing.html +17 -87
  549. nautobot/project-static/docs/development/core/user-preferences.html +17 -87
  550. nautobot/project-static/docs/development/index.html +17 -87
  551. nautobot/project-static/docs/development/jobs/index.html +424 -425
  552. nautobot/project-static/docs/development/jobs/migration/from-v1.html +75 -98
  553. nautobot/project-static/docs/development/react-ui.html +3 -3
  554. nautobot/project-static/docs/img/relationship_w_json_filter.png +0 -0
  555. nautobot/project-static/docs/index.html +90 -93
  556. nautobot/project-static/docs/media/admin_ui_run_permission.png +0 -0
  557. nautobot/project-static/docs/media/development/homepage_changelog_panel.png +0 -0
  558. nautobot/project-static/docs/media/development/homepage_dcim_panel.png +0 -0
  559. nautobot/project-static/docs/media/installation/nautobot_ui_admin.png +0 -0
  560. nautobot/project-static/docs/media/installation/nautobot_ui_login.png +0 -0
  561. nautobot/project-static/docs/media/models/dynamicgroup_filtering_01.png +0 -0
  562. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
  563. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
  564. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
  565. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
  566. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
  567. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
  568. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
  569. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
  570. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
  571. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
  572. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
  573. nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
  574. nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
  575. nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
  576. nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
  577. nautobot/project-static/docs/media/models/jobbutton_form.png +0 -0
  578. nautobot/project-static/docs/media/models/site_jobbuttons.png +0 -0
  579. nautobot/project-static/docs/media/plugins/plugin_admin_config.png +0 -0
  580. nautobot/project-static/docs/media/plugins/plugin_admin_ui.png +0 -0
  581. nautobot/project-static/docs/media/ss_config_contexts.png +0 -0
  582. nautobot/project-static/docs/media/ss_graphiql.png +0 -0
  583. nautobot/project-static/docs/media/ss_main_page.png +0 -0
  584. nautobot/project-static/docs/media/ss_plugin_chatops.png +0 -0
  585. nautobot/project-static/docs/media/ss_plugin_golden_config.png +0 -0
  586. nautobot/project-static/docs/media/ss_prefix_hierarchy.png +0 -0
  587. nautobot/project-static/docs/objects.inv +0 -0
  588. nautobot/project-static/docs/release-notes/index.html +17 -87
  589. nautobot/project-static/docs/release-notes/version-1.0.html +17 -87
  590. nautobot/project-static/docs/release-notes/version-1.1.html +17 -87
  591. nautobot/project-static/docs/release-notes/version-1.2.html +17 -87
  592. nautobot/project-static/docs/release-notes/version-1.3.html +17 -87
  593. nautobot/project-static/docs/release-notes/version-1.4.html +18 -88
  594. nautobot/project-static/docs/release-notes/version-1.5.html +17 -87
  595. nautobot/project-static/docs/release-notes/version-1.6.html +17 -87
  596. nautobot/project-static/docs/release-notes/version-2.0.html +467 -336
  597. nautobot/project-static/docs/release-notes/version-2.1.html +470 -108
  598. nautobot/project-static/docs/search/search_index.json +1 -1
  599. nautobot/project-static/docs/sitemap.xml +240 -255
  600. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  601. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +17 -87
  602. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +20 -90
  603. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +17 -87
  604. nautobot/project-static/docs/user-guide/administration/configuration/index.html +17 -87
  605. nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +13 -5417
  606. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +47 -113
  607. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +17 -87
  608. nautobot/project-static/docs/user-guide/administration/guides/caching.html +17 -87
  609. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +17 -87
  610. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +17 -87
  611. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +17 -87
  612. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +17 -87
  613. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +17 -87
  614. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +17 -87
  615. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +17 -87
  616. nautobot/project-static/docs/user-guide/administration/installation/docker.html +17 -87
  617. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +17 -87
  618. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +17 -87
  619. nautobot/project-static/docs/user-guide/administration/installation/index.html +22 -109
  620. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +18 -101
  621. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +23 -140
  622. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +17 -87
  623. nautobot/project-static/docs/user-guide/administration/installation/services.html +17 -87
  624. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +17 -87
  625. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +17 -87
  626. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +92 -181
  627. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +17 -87
  628. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +17 -87
  629. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +17 -87
  630. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +17 -87
  631. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +17 -87
  632. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +17 -87
  633. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +18 -88
  634. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +17 -87
  635. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +17 -87
  636. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +23 -89
  637. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +17 -87
  638. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +17 -87
  639. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +17 -87
  640. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +17 -87
  641. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +17 -87
  642. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +17 -87
  643. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +17 -87
  644. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +17 -87
  645. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +17 -87
  646. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +17 -87
  647. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +17 -87
  648. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +17 -87
  649. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +17 -87
  650. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +18 -88
  651. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +17 -87
  652. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +17 -87
  653. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +17 -87
  654. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +17 -87
  655. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +17 -87
  656. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +17 -87
  657. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +17 -87
  658. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +17 -87
  659. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +17 -87
  660. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +17 -87
  661. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +17 -87
  662. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +17 -87
  663. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +17 -87
  664. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +17 -87
  665. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +17 -87
  666. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +17 -87
  667. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +17 -87
  668. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +17 -87
  669. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +17 -87
  670. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +17 -87
  671. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +17 -87
  672. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +17 -87
  673. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +17 -87
  674. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +17 -87
  675. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +17 -87
  676. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +17 -87
  677. nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +259 -1
  678. nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.png +0 -0
  679. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +18 -88
  680. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +17 -87
  681. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +17 -87
  682. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +17 -87
  683. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +17 -87
  684. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +17 -87
  685. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +17 -87
  686. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +17 -87
  687. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +17 -87
  688. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +17 -87
  689. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +17 -87
  690. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +17 -87
  691. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +17 -87
  692. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +17 -87
  693. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +17 -87
  694. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +17 -87
  695. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +23 -93
  696. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +17 -87
  697. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +17 -87
  698. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +26 -96
  699. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +35 -103
  700. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +19 -89
  701. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +19 -91
  702. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +19 -89
  703. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +24 -94
  704. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +39 -258
  705. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -243
  706. nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
  707. nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
  708. nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
  709. nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
  710. nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
  711. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
  712. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
  713. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
  714. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
  715. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
  716. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
  717. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
  718. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
  719. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
  720. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
  721. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
  722. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
  723. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
  724. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
  725. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
  726. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
  727. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
  728. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
  729. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
  730. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
  731. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
  732. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
  733. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
  734. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
  735. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
  736. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
  737. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
  738. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
  739. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
  740. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
  741. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
  742. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
  743. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
  744. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
  745. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
  746. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
  747. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
  748. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
  749. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
  750. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
  751. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
  752. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
  753. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
  754. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
  755. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
  756. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
  757. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
  758. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
  759. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
  760. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
  761. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
  762. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
  763. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
  764. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
  765. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
  766. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
  767. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
  768. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
  769. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
  770. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
  771. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
  772. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
  773. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
  774. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
  775. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
  776. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
  777. nautobot/project-static/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
  778. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
  779. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
  780. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
  781. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
  782. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
  783. nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
  784. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
  785. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
  786. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
  787. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
  788. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
  789. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
  790. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
  791. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
  792. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
  793. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
  794. nautobot/project-static/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
  795. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +20 -90
  796. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +22 -92
  797. nautobot/project-static/docs/user-guide/index.html +17 -87
  798. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +17 -87
  799. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +17 -87
  800. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +17 -87
  801. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +17 -87
  802. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +22 -88
  803. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +17 -87
  804. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +68 -87
  805. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +18 -88
  806. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +17 -87
  807. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +17 -87
  808. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +17 -87
  809. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +17 -87
  810. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +17 -87
  811. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +22 -88
  812. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +17 -87
  813. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +17 -87
  814. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +17 -87
  815. nautobot/project-static/docs/user-guide/platform-functionality/note.html +17 -87
  816. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +18 -88
  817. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +17 -87
  818. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +17 -87
  819. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +17 -87
  820. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +17 -87
  821. nautobot/project-static/docs/user-guide/platform-functionality/role.html +17 -87
  822. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +17 -87
  823. nautobot/project-static/docs/user-guide/platform-functionality/status.html +17 -87
  824. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +17 -87
  825. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +43 -91
  826. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +21 -87
  827. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +17 -87
  828. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +17 -87
  829. nautobot/project-static/js/homepage_layout.js +170 -0
  830. nautobot/project-static/js/theme.js +0 -5
  831. nautobot/tenancy/api/urls.py +1 -1
  832. nautobot/tenancy/api/views.py +1 -0
  833. nautobot/tenancy/factory.py +2 -2
  834. nautobot/tenancy/filters/__init__.py +1 -2
  835. nautobot/tenancy/forms.py +2 -2
  836. nautobot/tenancy/homepage.py +0 -1
  837. nautobot/tenancy/migrations/0001_initial.py +2 -1
  838. nautobot/tenancy/migrations/0002_auto_slug.py +1 -0
  839. nautobot/tenancy/migrations/0004_change_tree_manager_on_tree_models.py +1 -0
  840. nautobot/tenancy/migrations/0008_tagsfield.py +1 -0
  841. nautobot/tenancy/models.py +0 -1
  842. nautobot/tenancy/navigation.py +0 -1
  843. nautobot/tenancy/tables.py +1 -0
  844. nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
  845. nautobot/tenancy/tests/test_filters.py +5 -5
  846. nautobot/tenancy/urls.py +1 -0
  847. nautobot/tenancy/views.py +2 -2
  848. nautobot/users/admin.py +1 -2
  849. nautobot/users/api/urls.py +1 -1
  850. nautobot/users/api/views.py +6 -4
  851. nautobot/users/factory.py +8 -24
  852. nautobot/users/filters.py +4 -4
  853. nautobot/users/forms.py +1 -0
  854. nautobot/users/migrations/0004_alter_user_managers.py +1 -0
  855. nautobot/users/migrations/0008_make_object_permission_a_changelogged_model.py +22 -0
  856. nautobot/users/models.py +2 -2
  857. nautobot/users/tests/test_api.py +7 -6
  858. nautobot/users/tests/test_filters.py +0 -1
  859. nautobot/users/tests/test_models.py +0 -1
  860. nautobot/users/tests/test_password_ui.py +1 -1
  861. nautobot/users/views.py +5 -4
  862. nautobot/virtualization/api/urls.py +1 -1
  863. nautobot/virtualization/api/views.py +2 -1
  864. nautobot/virtualization/apps.py +1 -1
  865. nautobot/virtualization/choices.py +0 -1
  866. nautobot/virtualization/factory.py +1 -1
  867. nautobot/virtualization/filters.py +1 -1
  868. nautobot/virtualization/forms.py +6 -6
  869. nautobot/virtualization/homepage.py +0 -1
  870. nautobot/virtualization/migrations/0003_vminterface_verbose_name.py +1 -0
  871. nautobot/virtualization/migrations/0004_auto_slug.py +1 -0
  872. nautobot/virtualization/migrations/0005_add_natural_indexing.py +1 -0
  873. nautobot/virtualization/migrations/0006_vminterface_status.py +1 -0
  874. nautobot/virtualization/migrations/0007_vminterface_status_data_migration.py +1 -0
  875. nautobot/virtualization/migrations/0011_alter_vminterface_mac_address.py +1 -0
  876. nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -0
  877. nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +1 -0
  878. nautobot/virtualization/migrations/0018_related_name_changes.py +1 -0
  879. nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +1 -0
  880. nautobot/virtualization/migrations/0025_status_nonnullable.py +1 -0
  881. nautobot/virtualization/models.py +1 -2
  882. nautobot/virtualization/navigation.py +0 -1
  883. nautobot/virtualization/signals.py +0 -1
  884. nautobot/virtualization/tables.py +1 -0
  885. nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -2
  886. nautobot/virtualization/tests/test_filters.py +3 -3
  887. nautobot/virtualization/tests/test_models.py +1 -1
  888. nautobot/virtualization/tests/test_views.py +2 -2
  889. nautobot/virtualization/urls.py +1 -0
  890. nautobot/virtualization/views.py +1 -1
  891. {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/METADATA +10 -2
  892. {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/RECORD +895 -993
  893. nautobot/core/management/commands/build_ui.py +0 -281
  894. nautobot/core/templates/base_react.html +0 -55
  895. nautobot/core/tests/test_cli.py +0 -25
  896. nautobot/project-static/docs/media/installation/nautobot_ui_guest.png +0 -0
  897. nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
  898. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
  899. nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
  900. nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
  901. nautobot/ui/.eslintignore +0 -3
  902. nautobot/ui/.gitignore +0 -7
  903. nautobot/ui/.prettierignore +0 -6
  904. nautobot/ui/.prettierrc +0 -4
  905. nautobot/ui/README.md +0 -27
  906. nautobot/ui/config/env.js +0 -102
  907. nautobot/ui/config/getHttpsConfig.js +0 -68
  908. nautobot/ui/config/jest/babelTransform.js +0 -14
  909. nautobot/ui/config/jest/cssTransform.js +0 -12
  910. nautobot/ui/config/jest/fileTransform.js +0 -38
  911. nautobot/ui/config/modules.js +0 -151
  912. nautobot/ui/config/paths.js +0 -67
  913. nautobot/ui/config/webpack/persistentCache/createEnvironmentHash.js +0 -8
  914. nautobot/ui/config/webpack.config.js +0 -674
  915. nautobot/ui/config/webpackDevServer.config.js +0 -127
  916. nautobot/ui/jest.config.js +0 -35
  917. nautobot/ui/jsconfig.json +0 -4
  918. nautobot/ui/package-lock.json +0 -22947
  919. nautobot/ui/package.json +0 -119
  920. nautobot/ui/public/index.html +0 -47
  921. nautobot/ui/public/logo192.png +0 -0
  922. nautobot/ui/public/logo512.png +0 -0
  923. nautobot/ui/public/manifest.json +0 -25
  924. nautobot/ui/public/nautobot_logo.svg +0 -131
  925. nautobot/ui/public/robots.txt +0 -3
  926. nautobot/ui/scripts/build.js +0 -224
  927. nautobot/ui/scripts/start.js +0 -140
  928. nautobot/ui/scripts/test.js +0 -40
  929. nautobot/ui/src/App.js +0 -79
  930. nautobot/ui/src/components/AppFullWidthComponents.js +0 -8
  931. nautobot/ui/src/components/AppTab.js +0 -40
  932. nautobot/ui/src/components/Apps.js +0 -60
  933. nautobot/ui/src/components/FeedbackModal.js +0 -123
  934. nautobot/ui/src/components/FiltersPanel.js +0 -693
  935. nautobot/ui/src/components/HomeChangelogPanel.js +0 -98
  936. nautobot/ui/src/components/HomePanel.js +0 -58
  937. nautobot/ui/src/components/JobHistoryTable.js +0 -78
  938. nautobot/ui/src/components/Layout.js +0 -76
  939. nautobot/ui/src/components/LoadingWidget.js +0 -14
  940. nautobot/ui/src/components/Navbar.js +0 -204
  941. nautobot/ui/src/components/NotificationPopover.js +0 -27
  942. nautobot/ui/src/components/ObjectTable/ObjectListTable.js +0 -300
  943. nautobot/ui/src/components/ObjectTable/ObjectTable.js +0 -96
  944. nautobot/ui/src/components/ObjectTable/ObjectTableItem.js +0 -70
  945. nautobot/ui/src/components/ObjectTable/index.js +0 -3
  946. nautobot/ui/src/components/Pagination/PageNumberForm.js +0 -228
  947. nautobot/ui/src/components/Pagination/PageSizeForm.js +0 -65
  948. nautobot/ui/src/components/Pagination/Pagination.js +0 -67
  949. nautobot/ui/src/components/Pagination/index.js +0 -3
  950. nautobot/ui/src/components/ReferenceDataTag.js +0 -35
  951. nautobot/ui/src/components/Retrieve/RenderChangeLogsTab.js +0 -58
  952. nautobot/ui/src/components/Retrieve/RenderColumn.js +0 -30
  953. nautobot/ui/src/components/Retrieve/RenderGroup.js +0 -24
  954. nautobot/ui/src/components/Retrieve/RenderHeader.js +0 -125
  955. nautobot/ui/src/components/Retrieve/RenderNotesTab.js +0 -60
  956. nautobot/ui/src/components/Retrieve/RenderTable.js +0 -33
  957. nautobot/ui/src/components/Retrieve/RenderTabs.js +0 -56
  958. nautobot/ui/src/components/Retrieve/index.js +0 -7
  959. nautobot/ui/src/components/RouterButton.js +0 -10
  960. nautobot/ui/src/components/RouterLink.js +0 -10
  961. nautobot/ui/src/components/SidebarNav.js +0 -156
  962. nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +0 -16
  963. nautobot/ui/src/components/__tests__/AppTab.test.js +0 -21
  964. nautobot/ui/src/components/__tests__/Apps.test.js +0 -14
  965. nautobot/ui/src/components/__tests__/Layout.test.js +0 -33
  966. nautobot/ui/src/components/__tests__/PageSizeForm.test.js +0 -13
  967. nautobot/ui/src/components/__tests__/Pagination.test.js +0 -43
  968. nautobot/ui/src/components/__tests__/Table.test.js +0 -39
  969. nautobot/ui/src/components/__tests__/TableItem.test.js +0 -39
  970. nautobot/ui/src/components/index.js +0 -4
  971. nautobot/ui/src/constants/apiPath.js +0 -13
  972. nautobot/ui/src/constants/icons.js +0 -15
  973. nautobot/ui/src/constants/size.js +0 -15
  974. nautobot/ui/src/file_templates/app_imports.js.j2 +0 -7
  975. nautobot/ui/src/file_templates/jsconfig-base.json +0 -12
  976. nautobot/ui/src/index.js +0 -65
  977. nautobot/ui/src/reportWebVitals.js +0 -15
  978. nautobot/ui/src/router.js +0 -77
  979. nautobot/ui/src/utils/api.js +0 -160
  980. nautobot/ui/src/utils/app-import.js +0 -15
  981. nautobot/ui/src/utils/color.js +0 -15
  982. nautobot/ui/src/utils/date.js +0 -14
  983. nautobot/ui/src/utils/index.js +0 -15
  984. nautobot/ui/src/utils/navigation.js +0 -48
  985. nautobot/ui/src/utils/session.js +0 -64
  986. nautobot/ui/src/utils/store.js +0 -242
  987. nautobot/ui/src/utils/string.js +0 -6
  988. nautobot/ui/src/utils/url.js +0 -4
  989. nautobot/ui/src/views/Home.js +0 -142
  990. nautobot/ui/src/views/InstalledApps.js +0 -80
  991. nautobot/ui/src/views/Login.js +0 -48
  992. nautobot/ui/src/views/Logout.js +0 -20
  993. nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +0 -11
  994. nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +0 -107
  995. nautobot/ui/src/views/__tests__/Login.test.js +0 -15
  996. nautobot/ui/src/views/generic/GenericView.js +0 -191
  997. nautobot/ui/src/views/generic/ObjectCreate.js +0 -96
  998. nautobot/ui/src/views/generic/ObjectList.js +0 -137
  999. nautobot/ui/src/views/generic/ObjectRetrieve.js +0 -87
  1000. {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/LICENSE.txt +0 -0
  1001. {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/WHEEL +0 -0
  1002. {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/entry_points.txt +0 -0
@@ -977,20 +977,6 @@
977
977
 
978
978
 
979
979
 
980
-
981
-
982
-
983
-
984
-
985
- <li class="md-nav__item">
986
- <a href="../../../user-guide/administration/configuration/node-configuration.html" class="md-nav__link">
987
- Node.js Configuration
988
- </a>
989
- </li>
990
-
991
-
992
-
993
-
994
980
  </ul>
995
981
  </nav>
996
982
  </li>
@@ -1439,34 +1425,6 @@
1439
1425
 
1440
1426
 
1441
1427
 
1442
- <li class="md-nav__item">
1443
- <a href="../../../user-guide/feature-guides/git-data-source.html" class="md-nav__link">
1444
- Git as a Data Source
1445
- </a>
1446
- </li>
1447
-
1448
-
1449
-
1450
-
1451
-
1452
-
1453
-
1454
-
1455
-
1456
- <li class="md-nav__item">
1457
- <a href="../../../user-guide/feature-guides/graphql.html" class="md-nav__link">
1458
- GraphQL
1459
- </a>
1460
- </li>
1461
-
1462
-
1463
-
1464
-
1465
-
1466
-
1467
-
1468
-
1469
-
1470
1428
  <li class="md-nav__item">
1471
1429
  <a href="../../../user-guide/feature-guides/relationships.html" class="md-nav__link">
1472
1430
  Relationships
@@ -3556,23 +3514,9 @@
3556
3514
 
3557
3515
 
3558
3516
 
3559
- <li class="md-nav__item">
3560
- <a href="../../../development/apps/api/views/view-overrides.html" class="md-nav__link">
3561
- View Overrides
3562
- </a>
3563
- </li>
3564
-
3565
-
3566
-
3567
-
3568
-
3569
-
3570
-
3571
-
3572
-
3573
3517
  <li class="md-nav__item">
3574
3518
  <a href="../../../development/apps/api/views/core-view-overrides.html" class="md-nav__link">
3575
- Legacy View Overrides
3519
+ View Overrides
3576
3520
  </a>
3577
3521
  </li>
3578
3522
 
@@ -3661,7 +3605,7 @@
3661
3605
 
3662
3606
  <li class="md-nav__item">
3663
3607
  <a href="../../../development/apps/api/platform-features/filter-extensions.html" class="md-nav__link">
3664
- Filter Extentions
3608
+ Filter Extensions
3665
3609
  </a>
3666
3610
  </li>
3667
3611
 
@@ -3869,21 +3813,7 @@
3869
3813
 
3870
3814
  <li class="md-nav__item">
3871
3815
  <a href="../../../development/apps/api/ui-extensions/object-detail-views.html" class="md-nav__link">
3872
- Object Detail Views
3873
- </a>
3874
- </li>
3875
-
3876
-
3877
-
3878
-
3879
-
3880
-
3881
-
3882
-
3883
-
3884
- <li class="md-nav__item">
3885
- <a href="../../../development/apps/api/ui-extensions/tabs.html" class="md-nav__link">
3886
- Tabs
3816
+ Object Detail Views and Tabs
3887
3817
  </a>
3888
3818
  </li>
3889
3819
 
@@ -4624,6 +4554,20 @@
4624
4554
 
4625
4555
 
4626
4556
 
4557
+ <li class="md-nav__item">
4558
+ <a href="../../../development/core/bootstrap-ui.html" class="md-nav__link">
4559
+ Bootstrap UI
4560
+ </a>
4561
+ </li>
4562
+
4563
+
4564
+
4565
+
4566
+
4567
+
4568
+
4569
+
4570
+
4627
4571
  <li class="md-nav__item">
4628
4572
  <a href="../../../development/core/best-practices.html" class="md-nav__link">
4629
4573
  Best Practices
@@ -4736,20 +4680,6 @@
4736
4680
 
4737
4681
 
4738
4682
 
4739
- <li class="md-nav__item">
4740
- <a href="../../../development/core/react-ui.html" class="md-nav__link">
4741
- React UI
4742
- </a>
4743
- </li>
4744
-
4745
-
4746
-
4747
-
4748
-
4749
-
4750
-
4751
-
4752
-
4753
4683
  <li class="md-nav__item">
4754
4684
  <a href="../../../development/core/role-internals.html" class="md-nav__link">
4755
4685
  Role Internals
@@ -5376,7 +5306,8 @@ Relationships, etc.</p>
5376
5306
 
5377
5307
  <details class="quote">
5378
5308
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
5379
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
5309
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-43"> 43</a></span>
5310
+ <span class="normal"><a href="#__codelineno-0-44"> 44</a></span>
5380
5311
  <span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
5381
5312
  <span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
5382
5313
  <span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
@@ -5593,226 +5524,225 @@ Relationships, etc.</p>
5593
5524
  <span class="normal"><a href="#__codelineno-0-258">258</a></span>
5594
5525
  <span class="normal"><a href="#__codelineno-0-259">259</a></span>
5595
5526
  <span class="normal"><a href="#__codelineno-0-260">260</a></span>
5596
- <span class="normal"><a href="#__codelineno-0-261">261</a></span>
5597
- <span class="normal"><a href="#__codelineno-0-262">262</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="k">class</span> <span class="nc">NautobotAppConfig</span><span class="p">(</span><span class="n">NautobotConfig</span><span class="p">):</span>
5598
- <a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
5599
- <a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> Subclass of Django&#39;s built-in AppConfig class, to be used for Nautobot plugins.</span>
5600
- <a id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="sd"> &quot;&quot;&quot;</span>
5601
- <a id="__codelineno-0-48" name="__codelineno-0-48"></a>
5602
- <a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="c1"># Plugin metadata</span>
5603
- <a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="n">author</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5604
- <a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="n">author_email</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5605
- <a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5606
- <a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5607
- <a id="__codelineno-0-54" name="__codelineno-0-54"></a>
5608
- <a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="c1"># Root URL path under /plugins. If not set, the plugin&#39;s label will be used.</span>
5609
- <a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">base_url</span> <span class="o">=</span> <span class="kc">None</span>
5610
- <a id="__codelineno-0-57" name="__codelineno-0-57"></a>
5611
- <a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="c1"># Minimum/maximum compatible versions of Nautobot</span>
5612
- <a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="kc">None</span>
5613
- <a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="kc">None</span>
5614
- <a id="__codelineno-0-61" name="__codelineno-0-61"></a>
5615
- <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="c1"># Default configuration parameters</span>
5616
- <a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">default_settings</span> <span class="o">=</span> <span class="p">{}</span>
5617
- <a id="__codelineno-0-64" name="__codelineno-0-64"></a>
5618
- <a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="c1"># Mandatory configuration parameters</span>
5619
- <a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">required_settings</span> <span class="o">=</span> <span class="p">[]</span>
5620
- <a id="__codelineno-0-67" name="__codelineno-0-67"></a>
5621
- <a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="c1"># Middleware classes provided by the plugin</span>
5622
- <a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">middleware</span> <span class="o">=</span> <span class="p">[]</span>
5623
- <a id="__codelineno-0-70" name="__codelineno-0-70"></a>
5624
- <a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="c1"># Extra installed apps provided or required by the plugin. These will be registered</span>
5625
- <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="c1"># along with the plugin.</span>
5626
- <a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">installed_apps</span> <span class="o">=</span> <span class="p">[]</span>
5627
- <a id="__codelineno-0-74" name="__codelineno-0-74"></a>
5628
- <a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="c1"># Default constance configuration parameters</span>
5629
- <a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">constance_config</span> <span class="o">=</span> <span class="p">{}</span>
5630
- <a id="__codelineno-0-77" name="__codelineno-0-77"></a>
5631
- <a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="c1"># URL reverse lookup names, a la &quot;plugins:myplugin:home&quot;, &quot;plugins:myplugin:configure&quot;, &quot;plugins:myplugin:docs&quot;</span>
5632
- <a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">home_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5633
- <a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">config_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5634
- <a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="n">docs_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5635
- <a id="__codelineno-0-82" name="__codelineno-0-82"></a>
5636
- <a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="c1"># Default integration paths. Plugin authors can override these to customize the paths to</span>
5637
- <a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="c1"># integrated components.</span>
5638
- <a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="s2">&quot;banner.banner&quot;</span>
5639
- <a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">custom_validators</span> <span class="o">=</span> <span class="s2">&quot;custom_validators.custom_validators&quot;</span>
5640
- <a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="s2">&quot;datasources.datasource_contents&quot;</span>
5641
- <a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="s2">&quot;filter_extensions.filter_extensions&quot;</span>
5642
- <a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="s2">&quot;graphql.types.graphql_types&quot;</span>
5643
- <a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="s2">&quot;homepage.layout&quot;</span>
5644
- <a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="n">jinja_filters</span> <span class="o">=</span> <span class="s2">&quot;jinja_filters&quot;</span>
5645
- <a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="s2">&quot;jobs.jobs&quot;</span>
5646
- <a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="s2">&quot;metrics.metrics&quot;</span>
5647
- <a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="s2">&quot;navigation.menu_items&quot;</span>
5648
- <a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="s2">&quot;secrets.secrets_providers&quot;</span>
5649
- <a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="s2">&quot;template_content.template_extensions&quot;</span>
5650
- <a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="s2">&quot;views.override_views&quot;</span>
5651
- <a id="__codelineno-0-98" name="__codelineno-0-98"></a>
5652
- <a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
5653
- <a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
5654
- <a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="c1"># We don&#39;t call super().ready here because we don&#39;t need or use the on-ready behavior of a core Nautobot app</span>
5655
- <a id="__codelineno-0-102" name="__codelineno-0-102"></a>
5656
- <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
5657
- <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.urls.urlpatterns&quot;</span><span class="p">)</span>
5658
- <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="n">api_urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.api.urls.urlpatterns&quot;</span><span class="p">)</span>
5659
- <a id="__codelineno-0-106" name="__codelineno-0-106"></a>
5660
- <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
5661
- <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5662
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">api_urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5663
- <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5664
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="p">),</span>
5665
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;models&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="p">()),</span>
5666
- <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5667
- <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5668
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5669
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">),</span>
5670
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;constance_config&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">constance_config</span><span class="p">,</span>
5671
- <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="p">}</span>
5672
- <a id="__codelineno-0-119" name="__codelineno-0-119"></a>
5673
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># Register banner function (if defined)</span>
5674
- <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">banner_function</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5675
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="k">if</span> <span class="n">banner_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5676
- <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
5677
- <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;banner&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5678
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a>
5679
- <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># Register model validators (if defined)</span>
5680
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">validators</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">custom_validators</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5681
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">if</span> <span class="n">validators</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5682
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
5683
- <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;custom_validators&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">validator</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">validator</span> <span class="ow">in</span> <span class="n">validators</span><span class="p">))</span>
5684
- <a id="__codelineno-0-131" name="__codelineno-0-131"></a>
5685
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="c1"># Register datasource contents (if defined)</span>
5686
- <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">datasource_contents</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5687
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="n">datasource_contents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5688
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
5689
- <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;datasource_contents&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">datasource_contents</span>
5690
- <a id="__codelineno-0-137" name="__codelineno-0-137"></a>
5691
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="c1"># Register GraphQL types (if defined)</span>
5692
- <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">graphql_types</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5693
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">if</span> <span class="n">graphql_types</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5694
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
5695
- <a id="__codelineno-0-142" name="__codelineno-0-142"></a>
5696
- <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="c1"># Import jobs (if present)</span>
5697
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jobs</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5698
- <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">if</span> <span class="n">jobs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5699
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
5700
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jobs&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">jobs</span>
5701
- <a id="__codelineno-0-148" name="__codelineno-0-148"></a>
5702
- <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Import metrics (if present)</span>
5703
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">metrics</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5704
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="k">if</span> <span class="n">metrics</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5705
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
5706
- <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;metrics&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Initialize as empty, to be filled by the signal handler</span>
5707
- <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
5708
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">signal_callback</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">discover_metrics</span><span class="p">,</span> <span class="n">metrics</span><span class="o">=</span><span class="n">metrics</span><span class="p">)</span>
5709
- <a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="n">nautobot_database_ready</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">signal_callback</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
5710
- <a id="__codelineno-0-157" name="__codelineno-0-157"></a>
5711
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
5712
- <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">menu_items</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5713
- <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">if</span> <span class="n">menu_items</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5714
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">register_plugin_menu_items</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">menu_items</span><span class="p">)</span>
5715
- <a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;nav_menu&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">menu_items</span>
5716
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a>
5717
- <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">homepage_layout</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5718
- <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="k">if</span> <span class="n">homepage_layout</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5719
- <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">register_homepage_panels</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="n">homepage_layout</span><span class="p">)</span>
5720
- <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;home_page&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">homepage_layout</span>
5721
- <a id="__codelineno-0-168" name="__codelineno-0-168"></a>
5722
- <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="c1"># Register template content (if defined)</span>
5723
- <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">template_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5724
- <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="k">if</span> <span class="n">template_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5725
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
5726
- <a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;template_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">extension</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">extension</span> <span class="ow">in</span> <span class="n">template_extensions</span><span class="p">))</span>
5727
- <a id="__codelineno-0-174" name="__codelineno-0-174"></a>
5728
- <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="c1"># Register custom jinja filters</span>
5729
- <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="k">try</span><span class="p">:</span>
5730
- <a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jinja_filters</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5731
- <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5732
- <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
5733
- <a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">pass</span>
5734
- <a id="__codelineno-0-181" name="__codelineno-0-181"></a>
5735
- <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="c1"># Register secrets providers (if any)</span>
5736
- <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">secrets_providers</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5737
- <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">if</span> <span class="n">secrets_providers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5738
- <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">for</span> <span class="n">secrets_provider</span> <span class="ow">in</span> <span class="n">secrets_providers</span><span class="p">:</span>
5739
- <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
5740
- <a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
5741
- <a id="__codelineno-0-188" name="__codelineno-0-188"></a>
5742
- <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="c1"># Register custom filters (if any)</span>
5743
- <a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">filter_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5744
- <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="k">if</span> <span class="n">filter_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5745
- <a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="n">register_filter_extensions</span><span class="p">(</span><span class="n">filter_extensions</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5746
- <a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="s2">&quot;filterform_fields&quot;</span><span class="p">:</span> <span class="p">[]}</span>
5747
- <a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">for</span> <span class="n">filter_extension</span> <span class="ow">in</span> <span class="n">filter_extensions</span><span class="p">:</span>
5748
- <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="k">for</span> <span class="n">filterset_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterset_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5749
- <a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5750
- <a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterset_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5751
- <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="p">)</span>
5752
- <a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="k">for</span> <span class="n">filterform_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterform_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5753
- <a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterform_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5754
- <a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterform_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5755
- <a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="p">)</span>
5756
- <a id="__codelineno-0-203" name="__codelineno-0-203"></a>
5757
- <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="c1"># Register override view (if any)</span>
5758
- <a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">override_views</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5759
- <a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="k">if</span> <span class="n">override_views</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5760
- <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="k">for</span> <span class="n">qualified_view_name</span><span class="p">,</span> <span class="n">view</span> <span class="ow">in</span> <span class="n">override_views</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5761
- <a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;overridden_views&quot;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5762
- <a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="p">(</span><span class="n">qualified_view_name</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5763
- <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="p">)</span>
5764
- <a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">register_override_views</span><span class="p">(</span><span class="n">override_views</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5765
- <a id="__codelineno-0-212" name="__codelineno-0-212"></a>
5766
- <a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="nd">@classmethod</span>
5767
- <a id="__codelineno-0-214" name="__codelineno-0-214"></a> <span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">user_config</span><span class="p">,</span> <span class="n">nautobot_version</span><span class="p">):</span>
5768
- <a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
5769
- <a id="__codelineno-0-216" name="__codelineno-0-216"></a>
5770
- <a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">plugin_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span>
5771
- <a id="__codelineno-0-218" name="__codelineno-0-218"></a>
5772
- <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="c1"># Enforce version constraints</span>
5773
- <a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">current_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">nautobot_version</span><span class="p">)</span>
5774
- <a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5775
- <a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="p">)</span>
5776
- <a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&lt;</span> <span class="n">min_version</span><span class="p">:</span>
5777
- <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5778
- <a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot minimum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="si">}</span><span class="s2">&quot;</span>
5779
- <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="p">)</span>
5780
- <a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5781
- <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="p">)</span>
5782
- <a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&gt;</span> <span class="n">max_version</span><span class="p">:</span>
5783
- <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5784
- <a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot maximum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="si">}</span><span class="s2">&quot;</span>
5785
- <a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="p">)</span>
5786
- <a id="__codelineno-0-233" name="__codelineno-0-233"></a>
5787
- <a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
5788
- <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
5789
- <a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
5790
- <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
5791
- <a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
5792
- <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5793
- <a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5794
- <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5795
- <a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="p">}</span>
5796
- <a id="__codelineno-0-243" name="__codelineno-0-243"></a>
5797
- <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># Validate user settings</span>
5798
- <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">for</span> <span class="n">setting_name</span><span class="p">,</span> <span class="n">setting_type</span> <span class="ow">in</span> <span class="n">setting_validations</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5799
- <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">setting_name</span><span class="p">),</span> <span class="n">setting_type</span><span class="p">):</span>
5800
- <a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">setting_name</span><span class="si">}</span><span class="s2"> must be a </span><span class="si">{</span><span class="n">setting_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5801
- <a id="__codelineno-0-248" name="__codelineno-0-248"></a>
5802
- <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="c1"># Validate the required_settings</span>
5803
- <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">for</span> <span class="n">setting</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">required_settings</span><span class="p">:</span>
5804
- <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span><span class="p">:</span>
5805
- <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5806
- <a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires &#39;</span><span class="si">{</span><span class="n">setting</span><span class="si">}</span><span class="s2">&#39; to be present in &quot;</span>
5807
- <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="sa">f</span><span class="s2">&quot;the PLUGINS_CONFIG[&#39;</span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2">&#39;] section of your settings.&quot;</span>
5808
- <a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="p">)</span>
5809
- <a id="__codelineno-0-256" name="__codelineno-0-256"></a>
5810
- <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="c1"># Apply default configuration values</span>
5811
- <a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="k">for</span> <span class="n">setting</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">default_settings</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5812
- <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># user_config and constance_config take precedence</span>
5813
- <a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
5814
- <a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span> <span class="ow">and</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">constance_config</span><span class="p">:</span>
5815
- <a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="n">user_config</span><span class="p">[</span><span class="n">setting</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
5527
+ <span class="normal"><a href="#__codelineno-0-261">261</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-43" name="__codelineno-0-43"></a><span class="k">class</span> <span class="nc">NautobotAppConfig</span><span class="p">(</span><span class="n">NautobotConfig</span><span class="p">):</span>
5528
+ <a id="__codelineno-0-44" name="__codelineno-0-44"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
5529
+ <a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="sd"> Subclass of Django&#39;s built-in AppConfig class, to be used for Nautobot plugins.</span>
5530
+ <a id="__codelineno-0-46" name="__codelineno-0-46"></a><span class="sd"> &quot;&quot;&quot;</span>
5531
+ <a id="__codelineno-0-47" name="__codelineno-0-47"></a>
5532
+ <a id="__codelineno-0-48" name="__codelineno-0-48"></a> <span class="c1"># Plugin metadata</span>
5533
+ <a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="n">author</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5534
+ <a id="__codelineno-0-50" name="__codelineno-0-50"></a> <span class="n">author_email</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5535
+ <a id="__codelineno-0-51" name="__codelineno-0-51"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5536
+ <a id="__codelineno-0-52" name="__codelineno-0-52"></a> <span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
5537
+ <a id="__codelineno-0-53" name="__codelineno-0-53"></a>
5538
+ <a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="c1"># Root URL path under /plugins. If not set, the plugin&#39;s label will be used.</span>
5539
+ <a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">base_url</span> <span class="o">=</span> <span class="kc">None</span>
5540
+ <a id="__codelineno-0-56" name="__codelineno-0-56"></a>
5541
+ <a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="c1"># Minimum/maximum compatible versions of Nautobot</span>
5542
+ <a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="kc">None</span>
5543
+ <a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="kc">None</span>
5544
+ <a id="__codelineno-0-60" name="__codelineno-0-60"></a>
5545
+ <a id="__codelineno-0-61" name="__codelineno-0-61"></a> <span class="c1"># Default configuration parameters</span>
5546
+ <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="n">default_settings</span> <span class="o">=</span> <span class="p">{}</span>
5547
+ <a id="__codelineno-0-63" name="__codelineno-0-63"></a>
5548
+ <a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="c1"># Mandatory configuration parameters</span>
5549
+ <a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="n">required_settings</span> <span class="o">=</span> <span class="p">[]</span>
5550
+ <a id="__codelineno-0-66" name="__codelineno-0-66"></a>
5551
+ <a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="c1"># Middleware classes provided by the plugin</span>
5552
+ <a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="n">middleware</span> <span class="o">=</span> <span class="p">[]</span>
5553
+ <a id="__codelineno-0-69" name="__codelineno-0-69"></a>
5554
+ <a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="c1"># Extra installed apps provided or required by the plugin. These will be registered</span>
5555
+ <a id="__codelineno-0-71" name="__codelineno-0-71"></a> <span class="c1"># along with the plugin.</span>
5556
+ <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="n">installed_apps</span> <span class="o">=</span> <span class="p">[]</span>
5557
+ <a id="__codelineno-0-73" name="__codelineno-0-73"></a>
5558
+ <a id="__codelineno-0-74" name="__codelineno-0-74"></a> <span class="c1"># Default constance configuration parameters</span>
5559
+ <a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="n">constance_config</span> <span class="o">=</span> <span class="p">{}</span>
5560
+ <a id="__codelineno-0-76" name="__codelineno-0-76"></a>
5561
+ <a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="c1"># URL reverse lookup names, a la &quot;plugins:myplugin:home&quot;, &quot;plugins:myplugin:configure&quot;, &quot;plugins:myplugin:docs&quot;</span>
5562
+ <a id="__codelineno-0-78" name="__codelineno-0-78"></a> <span class="n">home_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5563
+ <a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="n">config_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5564
+ <a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">docs_view_name</span> <span class="o">=</span> <span class="kc">None</span>
5565
+ <a id="__codelineno-0-81" name="__codelineno-0-81"></a>
5566
+ <a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="c1"># Default integration paths. Plugin authors can override these to customize the paths to</span>
5567
+ <a id="__codelineno-0-83" name="__codelineno-0-83"></a> <span class="c1"># integrated components.</span>
5568
+ <a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="s2">&quot;banner.banner&quot;</span>
5569
+ <a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">custom_validators</span> <span class="o">=</span> <span class="s2">&quot;custom_validators.custom_validators&quot;</span>
5570
+ <a id="__codelineno-0-86" name="__codelineno-0-86"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="s2">&quot;datasources.datasource_contents&quot;</span>
5571
+ <a id="__codelineno-0-87" name="__codelineno-0-87"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="s2">&quot;filter_extensions.filter_extensions&quot;</span>
5572
+ <a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="s2">&quot;graphql.types.graphql_types&quot;</span>
5573
+ <a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="s2">&quot;homepage.layout&quot;</span>
5574
+ <a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="n">jinja_filters</span> <span class="o">=</span> <span class="s2">&quot;jinja_filters&quot;</span>
5575
+ <a id="__codelineno-0-91" name="__codelineno-0-91"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="s2">&quot;jobs.jobs&quot;</span>
5576
+ <a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="s2">&quot;metrics.metrics&quot;</span>
5577
+ <a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="s2">&quot;navigation.menu_items&quot;</span>
5578
+ <a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="s2">&quot;secrets.secrets_providers&quot;</span>
5579
+ <a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="s2">&quot;template_content.template_extensions&quot;</span>
5580
+ <a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="s2">&quot;views.override_views&quot;</span>
5581
+ <a id="__codelineno-0-97" name="__codelineno-0-97"></a>
5582
+ <a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
5583
+ <a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
5584
+ <a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="c1"># We don&#39;t call super().ready here because we don&#39;t need or use the on-ready behavior of a core Nautobot app</span>
5585
+ <a id="__codelineno-0-101" name="__codelineno-0-101"></a>
5586
+ <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
5587
+ <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.urls.urlpatterns&quot;</span><span class="p">)</span>
5588
+ <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">api_urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.api.urls.urlpatterns&quot;</span><span class="p">)</span>
5589
+ <a id="__codelineno-0-105" name="__codelineno-0-105"></a>
5590
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
5591
+ <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5592
+ <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">api_urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5593
+ <a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5594
+ <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="p">),</span>
5595
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="s2">&quot;models&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="p">()),</span>
5596
+ <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5597
+ <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5598
+ <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5599
+ <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="p">),</span>
5600
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="s2">&quot;constance_config&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">constance_config</span><span class="p">,</span>
5601
+ <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="p">}</span>
5602
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a>
5603
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="c1"># Register banner function (if defined)</span>
5604
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">banner_function</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5605
+ <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">if</span> <span class="n">banner_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5606
+ <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
5607
+ <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;banner&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5608
+ <a id="__codelineno-0-124" name="__codelineno-0-124"></a>
5609
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="c1"># Register model validators (if defined)</span>
5610
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="n">validators</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">custom_validators</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5611
+ <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">if</span> <span class="n">validators</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5612
+ <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
5613
+ <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;custom_validators&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">validator</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">validator</span> <span class="ow">in</span> <span class="n">validators</span><span class="p">))</span>
5614
+ <a id="__codelineno-0-130" name="__codelineno-0-130"></a>
5615
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="c1"># Register datasource contents (if defined)</span>
5616
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">datasource_contents</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5617
+ <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">if</span> <span class="n">datasource_contents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5618
+ <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
5619
+ <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;datasource_contents&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">datasource_contents</span>
5620
+ <a id="__codelineno-0-136" name="__codelineno-0-136"></a>
5621
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="c1"># Register GraphQL types (if defined)</span>
5622
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">graphql_types</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5623
+ <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">if</span> <span class="n">graphql_types</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5624
+ <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
5625
+ <a id="__codelineno-0-141" name="__codelineno-0-141"></a>
5626
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="c1"># Import jobs (if present)</span>
5627
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jobs</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5628
+ <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="k">if</span> <span class="n">jobs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5629
+ <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
5630
+ <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jobs&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">jobs</span>
5631
+ <a id="__codelineno-0-147" name="__codelineno-0-147"></a>
5632
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="c1"># Import metrics (if present)</span>
5633
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">metrics</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5634
+ <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">if</span> <span class="n">metrics</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5635
+ <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
5636
+ <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;metrics&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Initialize as empty, to be filled by the signal handler</span>
5637
+ <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
5638
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">signal_callback</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">discover_metrics</span><span class="p">,</span> <span class="n">metrics</span><span class="o">=</span><span class="n">metrics</span><span class="p">)</span>
5639
+ <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">nautobot_database_ready</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">signal_callback</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
5640
+ <a id="__codelineno-0-156" name="__codelineno-0-156"></a>
5641
+ <a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
5642
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">menu_items</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5643
+ <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="k">if</span> <span class="n">menu_items</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5644
+ <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="n">register_plugin_menu_items</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">menu_items</span><span class="p">)</span>
5645
+ <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;nav_menu&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">menu_items</span>
5646
+ <a id="__codelineno-0-162" name="__codelineno-0-162"></a>
5647
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">homepage_layout</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5648
+ <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">if</span> <span class="n">homepage_layout</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5649
+ <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">register_homepage_panels</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="n">homepage_layout</span><span class="p">)</span>
5650
+ <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;home_page&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">homepage_layout</span>
5651
+ <a id="__codelineno-0-167" name="__codelineno-0-167"></a>
5652
+ <a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="c1"># Register template content (if defined)</span>
5653
+ <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">template_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5654
+ <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">if</span> <span class="n">template_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5655
+ <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
5656
+ <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;template_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">extension</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">extension</span> <span class="ow">in</span> <span class="n">template_extensions</span><span class="p">))</span>
5657
+ <a id="__codelineno-0-173" name="__codelineno-0-173"></a>
5658
+ <a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="c1"># Register custom jinja filters</span>
5659
+ <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="k">try</span><span class="p">:</span>
5660
+ <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jinja_filters</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5661
+ <a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5662
+ <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
5663
+ <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">pass</span>
5664
+ <a id="__codelineno-0-180" name="__codelineno-0-180"></a>
5665
+ <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="c1"># Register secrets providers (if any)</span>
5666
+ <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">secrets_providers</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5667
+ <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="k">if</span> <span class="n">secrets_providers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5668
+ <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">for</span> <span class="n">secrets_provider</span> <span class="ow">in</span> <span class="n">secrets_providers</span><span class="p">:</span>
5669
+ <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
5670
+ <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
5671
+ <a id="__codelineno-0-187" name="__codelineno-0-187"></a>
5672
+ <a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="c1"># Register custom filters (if any)</span>
5673
+ <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">filter_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5674
+ <a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="k">if</span> <span class="n">filter_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5675
+ <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="n">register_filter_extensions</span><span class="p">(</span><span class="n">filter_extensions</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5676
+ <a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="s2">&quot;filterform_fields&quot;</span><span class="p">:</span> <span class="p">[]}</span>
5677
+ <a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="k">for</span> <span class="n">filter_extension</span> <span class="ow">in</span> <span class="n">filter_extensions</span><span class="p">:</span>
5678
+ <a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">for</span> <span class="n">filterset_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterset_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5679
+ <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5680
+ <a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterset_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5681
+ <a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="p">)</span>
5682
+ <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="k">for</span> <span class="n">filterform_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterform_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5683
+ <a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterform_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5684
+ <a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterform_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5685
+ <a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="p">)</span>
5686
+ <a id="__codelineno-0-202" name="__codelineno-0-202"></a>
5687
+ <a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="c1"># Register override view (if any)</span>
5688
+ <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">override_views</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5689
+ <a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">if</span> <span class="n">override_views</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5690
+ <a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="k">for</span> <span class="n">qualified_view_name</span><span class="p">,</span> <span class="n">view</span> <span class="ow">in</span> <span class="n">override_views</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5691
+ <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;overridden_views&quot;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5692
+ <a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="p">(</span><span class="n">qualified_view_name</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5693
+ <a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="p">)</span>
5694
+ <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">register_override_views</span><span class="p">(</span><span class="n">override_views</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5695
+ <a id="__codelineno-0-211" name="__codelineno-0-211"></a>
5696
+ <a id="__codelineno-0-212" name="__codelineno-0-212"></a> <span class="nd">@classmethod</span>
5697
+ <a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">user_config</span><span class="p">,</span> <span class="n">nautobot_version</span><span class="p">):</span>
5698
+ <a id="__codelineno-0-214" name="__codelineno-0-214"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
5699
+ <a id="__codelineno-0-215" name="__codelineno-0-215"></a>
5700
+ <a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">plugin_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span>
5701
+ <a id="__codelineno-0-217" name="__codelineno-0-217"></a>
5702
+ <a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="c1"># Enforce version constraints</span>
5703
+ <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="n">current_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">nautobot_version</span><span class="p">)</span>
5704
+ <a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5705
+ <a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="p">)</span>
5706
+ <a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&lt;</span> <span class="n">min_version</span><span class="p">:</span>
5707
+ <a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5708
+ <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot minimum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="si">}</span><span class="s2">&quot;</span>
5709
+ <a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="p">)</span>
5710
+ <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5711
+ <a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="p">)</span>
5712
+ <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&gt;</span> <span class="n">max_version</span><span class="p">:</span>
5713
+ <a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5714
+ <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot maximum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="si">}</span><span class="s2">&quot;</span>
5715
+ <a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="p">)</span>
5716
+ <a id="__codelineno-0-232" name="__codelineno-0-232"></a>
5717
+ <a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
5718
+ <a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
5719
+ <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
5720
+ <a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
5721
+ <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
5722
+ <a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5723
+ <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5724
+ <a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
5725
+ <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="p">}</span>
5726
+ <a id="__codelineno-0-242" name="__codelineno-0-242"></a>
5727
+ <a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="c1"># Validate user settings</span>
5728
+ <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="k">for</span> <span class="n">setting_name</span><span class="p">,</span> <span class="n">setting_type</span> <span class="ow">in</span> <span class="n">setting_validations</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5729
+ <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">setting_name</span><span class="p">),</span> <span class="n">setting_type</span><span class="p">):</span>
5730
+ <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">setting_name</span><span class="si">}</span><span class="s2"> must be a </span><span class="si">{</span><span class="n">setting_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5731
+ <a id="__codelineno-0-247" name="__codelineno-0-247"></a>
5732
+ <a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="c1"># Validate the required_settings</span>
5733
+ <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="k">for</span> <span class="n">setting</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">required_settings</span><span class="p">:</span>
5734
+ <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span><span class="p">:</span>
5735
+ <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
5736
+ <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires &#39;</span><span class="si">{</span><span class="n">setting</span><span class="si">}</span><span class="s2">&#39; to be present in &quot;</span>
5737
+ <a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="sa">f</span><span class="s2">&quot;the PLUGINS_CONFIG[&#39;</span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2">&#39;] section of your settings.&quot;</span>
5738
+ <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="p">)</span>
5739
+ <a id="__codelineno-0-255" name="__codelineno-0-255"></a>
5740
+ <a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="c1"># Apply default configuration values</span>
5741
+ <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="k">for</span> <span class="n">setting</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">default_settings</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5742
+ <a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="c1"># user_config and constance_config take precedence</span>
5743
+ <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
5744
+ <a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span> <span class="ow">and</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">constance_config</span><span class="p">:</span>
5745
+ <a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="n">user_config</span><span class="p">[</span><span class="n">setting</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
5816
5746
  </code></pre></div></td></tr></table></div>
5817
5747
  </details>
5818
5748
 
@@ -5845,7 +5775,8 @@ Relationships, etc.</p>
5845
5775
 
5846
5776
  <details class="quote">
5847
5777
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
5848
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
5778
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-98"> 98</a></span>
5779
+ <span class="normal"><a href="#__codelineno-0-99"> 99</a></span>
5849
5780
  <span class="normal"><a href="#__codelineno-0-100">100</a></span>
5850
5781
  <span class="normal"><a href="#__codelineno-0-101">101</a></span>
5851
5782
  <span class="normal"><a href="#__codelineno-0-102">102</a></span>
@@ -5956,120 +5887,119 @@ Relationships, etc.</p>
5956
5887
  <span class="normal"><a href="#__codelineno-0-207">207</a></span>
5957
5888
  <span class="normal"><a href="#__codelineno-0-208">208</a></span>
5958
5889
  <span class="normal"><a href="#__codelineno-0-209">209</a></span>
5959
- <span class="normal"><a href="#__codelineno-0-210">210</a></span>
5960
- <span class="normal"><a href="#__codelineno-0-211">211</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
5961
- <a id="__codelineno-0-100" name="__codelineno-0-100"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
5962
- <a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="c1"># We don&#39;t call super().ready here because we don&#39;t need or use the on-ready behavior of a core Nautobot app</span>
5963
- <a id="__codelineno-0-102" name="__codelineno-0-102"></a>
5964
- <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
5965
- <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.urls.urlpatterns&quot;</span><span class="p">)</span>
5966
- <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="n">api_urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.api.urls.urlpatterns&quot;</span><span class="p">)</span>
5967
- <a id="__codelineno-0-106" name="__codelineno-0-106"></a>
5968
- <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
5969
- <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5970
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">api_urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5971
- <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5972
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="p">),</span>
5973
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;models&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="p">()),</span>
5974
- <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5975
- <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5976
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5977
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">),</span>
5978
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;constance_config&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">constance_config</span><span class="p">,</span>
5979
- <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="p">}</span>
5980
- <a id="__codelineno-0-119" name="__codelineno-0-119"></a>
5981
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># Register banner function (if defined)</span>
5982
- <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">banner_function</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5983
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="k">if</span> <span class="n">banner_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5984
- <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
5985
- <a id="__codelineno-0-124" name="__codelineno-0-124"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;banner&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5986
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a>
5987
- <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># Register model validators (if defined)</span>
5988
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="n">validators</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">custom_validators</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5989
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="k">if</span> <span class="n">validators</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5990
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
5991
- <a id="__codelineno-0-130" name="__codelineno-0-130"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;custom_validators&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">validator</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">validator</span> <span class="ow">in</span> <span class="n">validators</span><span class="p">))</span>
5992
- <a id="__codelineno-0-131" name="__codelineno-0-131"></a>
5993
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="c1"># Register datasource contents (if defined)</span>
5994
- <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">datasource_contents</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5995
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="k">if</span> <span class="n">datasource_contents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5996
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
5997
- <a id="__codelineno-0-136" name="__codelineno-0-136"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;datasource_contents&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">datasource_contents</span>
5998
- <a id="__codelineno-0-137" name="__codelineno-0-137"></a>
5999
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="c1"># Register GraphQL types (if defined)</span>
6000
- <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">graphql_types</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6001
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="k">if</span> <span class="n">graphql_types</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6002
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
6003
- <a id="__codelineno-0-142" name="__codelineno-0-142"></a>
6004
- <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="c1"># Import jobs (if present)</span>
6005
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jobs</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6006
- <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="k">if</span> <span class="n">jobs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6007
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
6008
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jobs&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">jobs</span>
6009
- <a id="__codelineno-0-148" name="__codelineno-0-148"></a>
6010
- <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Import metrics (if present)</span>
6011
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">metrics</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6012
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="k">if</span> <span class="n">metrics</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6013
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
6014
- <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;metrics&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Initialize as empty, to be filled by the signal handler</span>
6015
- <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
6016
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">signal_callback</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">discover_metrics</span><span class="p">,</span> <span class="n">metrics</span><span class="o">=</span><span class="n">metrics</span><span class="p">)</span>
6017
- <a id="__codelineno-0-156" name="__codelineno-0-156"></a> <span class="n">nautobot_database_ready</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">signal_callback</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
6018
- <a id="__codelineno-0-157" name="__codelineno-0-157"></a>
6019
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
6020
- <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">menu_items</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6021
- <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="k">if</span> <span class="n">menu_items</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6022
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">register_plugin_menu_items</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">menu_items</span><span class="p">)</span>
6023
- <a id="__codelineno-0-162" name="__codelineno-0-162"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;nav_menu&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">menu_items</span>
6024
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a>
6025
- <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">homepage_layout</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6026
- <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="k">if</span> <span class="n">homepage_layout</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6027
- <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="n">register_homepage_panels</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="n">homepage_layout</span><span class="p">)</span>
6028
- <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;home_page&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">homepage_layout</span>
6029
- <a id="__codelineno-0-168" name="__codelineno-0-168"></a>
6030
- <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="c1"># Register template content (if defined)</span>
6031
- <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">template_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6032
- <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="k">if</span> <span class="n">template_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6033
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
6034
- <a id="__codelineno-0-173" name="__codelineno-0-173"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;template_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">extension</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">extension</span> <span class="ow">in</span> <span class="n">template_extensions</span><span class="p">))</span>
6035
- <a id="__codelineno-0-174" name="__codelineno-0-174"></a>
6036
- <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="c1"># Register custom jinja filters</span>
6037
- <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="k">try</span><span class="p">:</span>
6038
- <a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jinja_filters</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6039
- <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
6040
- <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
6041
- <a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">pass</span>
6042
- <a id="__codelineno-0-181" name="__codelineno-0-181"></a>
6043
- <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="c1"># Register secrets providers (if any)</span>
6044
- <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">secrets_providers</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6045
- <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">if</span> <span class="n">secrets_providers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6046
- <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">for</span> <span class="n">secrets_provider</span> <span class="ow">in</span> <span class="n">secrets_providers</span><span class="p">:</span>
6047
- <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
6048
- <a id="__codelineno-0-187" name="__codelineno-0-187"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
6049
- <a id="__codelineno-0-188" name="__codelineno-0-188"></a>
6050
- <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="c1"># Register custom filters (if any)</span>
6051
- <a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">filter_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6052
- <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="k">if</span> <span class="n">filter_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6053
- <a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="n">register_filter_extensions</span><span class="p">(</span><span class="n">filter_extensions</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
6054
- <a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="s2">&quot;filterform_fields&quot;</span><span class="p">:</span> <span class="p">[]}</span>
6055
- <a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">for</span> <span class="n">filter_extension</span> <span class="ow">in</span> <span class="n">filter_extensions</span><span class="p">:</span>
6056
- <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="k">for</span> <span class="n">filterset_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterset_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
6057
- <a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
6058
- <a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterset_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
6059
- <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="p">)</span>
6060
- <a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="k">for</span> <span class="n">filterform_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterform_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
6061
- <a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterform_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
6062
- <a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterform_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
6063
- <a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="p">)</span>
6064
- <a id="__codelineno-0-203" name="__codelineno-0-203"></a>
6065
- <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="c1"># Register override view (if any)</span>
6066
- <a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">override_views</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6067
- <a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="k">if</span> <span class="n">override_views</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6068
- <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="k">for</span> <span class="n">qualified_view_name</span><span class="p">,</span> <span class="n">view</span> <span class="ow">in</span> <span class="n">override_views</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
6069
- <a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;overridden_views&quot;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
6070
- <a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="p">(</span><span class="n">qualified_view_name</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6071
- <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="p">)</span>
6072
- <a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="n">register_override_views</span><span class="p">(</span><span class="n">override_views</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5890
+ <span class="normal"><a href="#__codelineno-0-210">210</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-98" name="__codelineno-0-98"></a><span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
5891
+ <a id="__codelineno-0-99" name="__codelineno-0-99"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
5892
+ <a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="c1"># We don&#39;t call super().ready here because we don&#39;t need or use the on-ready behavior of a core Nautobot app</span>
5893
+ <a id="__codelineno-0-101" name="__codelineno-0-101"></a>
5894
+ <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
5895
+ <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.urls.urlpatterns&quot;</span><span class="p">)</span>
5896
+ <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">api_urlpatterns</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.api.urls.urlpatterns&quot;</span><span class="p">)</span>
5897
+ <a id="__codelineno-0-105" name="__codelineno-0-105"></a>
5898
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
5899
+ <a id="__codelineno-0-107" name="__codelineno-0-107"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5900
+ <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">api_urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5901
+ <a id="__codelineno-0-109" name="__codelineno-0-109"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5902
+ <a id="__codelineno-0-110" name="__codelineno-0-110"></a> <span class="p">),</span>
5903
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="s2">&quot;models&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_models</span><span class="p">()),</span>
5904
+ <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
5905
+ <a id="__codelineno-0-113" name="__codelineno-0-113"></a> <span class="p">(</span><span class="n">urlp</span> <span class="k">for</span> <span class="n">urlp</span> <span class="ow">in</span> <span class="p">(</span><span class="n">urlpatterns</span> <span class="ow">or</span> <span class="p">[])</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">urlp</span><span class="p">,</span> <span class="n">URLPattern</span><span class="p">)),</span>
5906
+ <a id="__codelineno-0-114" name="__codelineno-0-114"></a> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">urlp</span><span class="p">:</span> <span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">urlp</span><span class="o">.</span><span class="n">pattern</span><span class="p">)),</span>
5907
+ <a id="__codelineno-0-115" name="__codelineno-0-115"></a> <span class="p">),</span>
5908
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="s2">&quot;constance_config&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">constance_config</span><span class="p">,</span>
5909
+ <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="p">}</span>
5910
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a>
5911
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a> <span class="c1"># Register banner function (if defined)</span>
5912
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">banner_function</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5913
+ <a id="__codelineno-0-121" name="__codelineno-0-121"></a> <span class="k">if</span> <span class="n">banner_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5914
+ <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
5915
+ <a id="__codelineno-0-123" name="__codelineno-0-123"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;banner&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5916
+ <a id="__codelineno-0-124" name="__codelineno-0-124"></a>
5917
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="c1"># Register model validators (if defined)</span>
5918
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="n">validators</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">custom_validators</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5919
+ <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="k">if</span> <span class="n">validators</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5920
+ <a id="__codelineno-0-128" name="__codelineno-0-128"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
5921
+ <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;custom_validators&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">validator</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">validator</span> <span class="ow">in</span> <span class="n">validators</span><span class="p">))</span>
5922
+ <a id="__codelineno-0-130" name="__codelineno-0-130"></a>
5923
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a> <span class="c1"># Register datasource contents (if defined)</span>
5924
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">datasource_contents</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5925
+ <a id="__codelineno-0-133" name="__codelineno-0-133"></a> <span class="k">if</span> <span class="n">datasource_contents</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5926
+ <a id="__codelineno-0-134" name="__codelineno-0-134"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
5927
+ <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;datasource_contents&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">datasource_contents</span>
5928
+ <a id="__codelineno-0-136" name="__codelineno-0-136"></a>
5929
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a> <span class="c1"># Register GraphQL types (if defined)</span>
5930
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">graphql_types</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5931
+ <a id="__codelineno-0-139" name="__codelineno-0-139"></a> <span class="k">if</span> <span class="n">graphql_types</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5932
+ <a id="__codelineno-0-140" name="__codelineno-0-140"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
5933
+ <a id="__codelineno-0-141" name="__codelineno-0-141"></a>
5934
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a> <span class="c1"># Import jobs (if present)</span>
5935
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jobs</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5936
+ <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="k">if</span> <span class="n">jobs</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5937
+ <a id="__codelineno-0-145" name="__codelineno-0-145"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
5938
+ <a id="__codelineno-0-146" name="__codelineno-0-146"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jobs&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">jobs</span>
5939
+ <a id="__codelineno-0-147" name="__codelineno-0-147"></a>
5940
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a> <span class="c1"># Import metrics (if present)</span>
5941
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">metrics</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5942
+ <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="k">if</span> <span class="n">metrics</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5943
+ <a id="__codelineno-0-151" name="__codelineno-0-151"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
5944
+ <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;metrics&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Initialize as empty, to be filled by the signal handler</span>
5945
+ <a id="__codelineno-0-153" name="__codelineno-0-153"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
5946
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="n">signal_callback</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">discover_metrics</span><span class="p">,</span> <span class="n">metrics</span><span class="o">=</span><span class="n">metrics</span><span class="p">)</span>
5947
+ <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">nautobot_database_ready</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">signal_callback</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="p">)</span>
5948
+ <a id="__codelineno-0-156" name="__codelineno-0-156"></a>
5949
+ <a id="__codelineno-0-157" name="__codelineno-0-157"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
5950
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">menu_items</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5951
+ <a id="__codelineno-0-159" name="__codelineno-0-159"></a> <span class="k">if</span> <span class="n">menu_items</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5952
+ <a id="__codelineno-0-160" name="__codelineno-0-160"></a> <span class="n">register_plugin_menu_items</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">menu_items</span><span class="p">)</span>
5953
+ <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;nav_menu&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">menu_items</span>
5954
+ <a id="__codelineno-0-162" name="__codelineno-0-162"></a>
5955
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">homepage_layout</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5956
+ <a id="__codelineno-0-164" name="__codelineno-0-164"></a> <span class="k">if</span> <span class="n">homepage_layout</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5957
+ <a id="__codelineno-0-165" name="__codelineno-0-165"></a> <span class="n">register_homepage_panels</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="n">homepage_layout</span><span class="p">)</span>
5958
+ <a id="__codelineno-0-166" name="__codelineno-0-166"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;home_page&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">homepage_layout</span>
5959
+ <a id="__codelineno-0-167" name="__codelineno-0-167"></a>
5960
+ <a id="__codelineno-0-168" name="__codelineno-0-168"></a> <span class="c1"># Register template content (if defined)</span>
5961
+ <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">template_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5962
+ <a id="__codelineno-0-170" name="__codelineno-0-170"></a> <span class="k">if</span> <span class="n">template_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5963
+ <a id="__codelineno-0-171" name="__codelineno-0-171"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
5964
+ <a id="__codelineno-0-172" name="__codelineno-0-172"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;template_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">extension</span><span class="o">.</span><span class="n">model</span> <span class="k">for</span> <span class="n">extension</span> <span class="ow">in</span> <span class="n">template_extensions</span><span class="p">))</span>
5965
+ <a id="__codelineno-0-173" name="__codelineno-0-173"></a>
5966
+ <a id="__codelineno-0-174" name="__codelineno-0-174"></a> <span class="c1"># Register custom jinja filters</span>
5967
+ <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="k">try</span><span class="p">:</span>
5968
+ <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="n">import_module</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">jinja_filters</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5969
+ <a id="__codelineno-0-177" name="__codelineno-0-177"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
5970
+ <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
5971
+ <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">pass</span>
5972
+ <a id="__codelineno-0-180" name="__codelineno-0-180"></a>
5973
+ <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="c1"># Register secrets providers (if any)</span>
5974
+ <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">secrets_providers</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5975
+ <a id="__codelineno-0-183" name="__codelineno-0-183"></a> <span class="k">if</span> <span class="n">secrets_providers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5976
+ <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="k">for</span> <span class="n">secrets_provider</span> <span class="ow">in</span> <span class="n">secrets_providers</span><span class="p">:</span>
5977
+ <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
5978
+ <a id="__codelineno-0-186" name="__codelineno-0-186"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
5979
+ <a id="__codelineno-0-187" name="__codelineno-0-187"></a>
5980
+ <a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="c1"># Register custom filters (if any)</span>
5981
+ <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">filter_extensions</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5982
+ <a id="__codelineno-0-190" name="__codelineno-0-190"></a> <span class="k">if</span> <span class="n">filter_extensions</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5983
+ <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="n">register_filter_extensions</span><span class="p">(</span><span class="n">filter_extensions</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
5984
+ <a id="__codelineno-0-192" name="__codelineno-0-192"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="s2">&quot;filterform_fields&quot;</span><span class="p">:</span> <span class="p">[]}</span>
5985
+ <a id="__codelineno-0-193" name="__codelineno-0-193"></a> <span class="k">for</span> <span class="n">filter_extension</span> <span class="ow">in</span> <span class="n">filter_extensions</span><span class="p">:</span>
5986
+ <a id="__codelineno-0-194" name="__codelineno-0-194"></a> <span class="k">for</span> <span class="n">filterset_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterset_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5987
+ <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterset_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5988
+ <a id="__codelineno-0-196" name="__codelineno-0-196"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterset_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5989
+ <a id="__codelineno-0-197" name="__codelineno-0-197"></a> <span class="p">)</span>
5990
+ <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="k">for</span> <span class="n">filterform_field_name</span> <span class="ow">in</span> <span class="n">filter_extension</span><span class="o">.</span><span class="n">filterform_fields</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
5991
+ <a id="__codelineno-0-199" name="__codelineno-0-199"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="p">[</span><span class="s2">&quot;filter_extensions&quot;</span><span class="p">][</span><span class="s2">&quot;filterform_fields&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
5992
+ <a id="__codelineno-0-200" name="__codelineno-0-200"></a> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">filter_extension</span><span class="o">.</span><span class="n">model</span><span class="si">}</span><span class="s2"> -&gt; </span><span class="si">{</span><span class="n">filterform_field_name</span><span class="si">}</span><span class="s2">&quot;</span>
5993
+ <a id="__codelineno-0-201" name="__codelineno-0-201"></a> <span class="p">)</span>
5994
+ <a id="__codelineno-0-202" name="__codelineno-0-202"></a>
5995
+ <a id="__codelineno-0-203" name="__codelineno-0-203"></a> <span class="c1"># Register override view (if any)</span>
5996
+ <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="n">import_object</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">override_views</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
5997
+ <a id="__codelineno-0-205" name="__codelineno-0-205"></a> <span class="k">if</span> <span class="n">override_views</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
5998
+ <a id="__codelineno-0-206" name="__codelineno-0-206"></a> <span class="k">for</span> <span class="n">qualified_view_name</span><span class="p">,</span> <span class="n">view</span> <span class="ow">in</span> <span class="n">override_views</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
5999
+ <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;overridden_views&quot;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
6000
+ <a id="__codelineno-0-208" name="__codelineno-0-208"></a> <span class="p">(</span><span class="n">qualified_view_name</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__module__</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">view</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6001
+ <a id="__codelineno-0-209" name="__codelineno-0-209"></a> <span class="p">)</span>
6002
+ <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="n">register_override_views</span><span class="p">(</span><span class="n">override_views</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
6073
6003
  </code></pre></div></td></tr></table></div>
6074
6004
  </details>
6075
6005
  </div>
@@ -6097,7 +6027,8 @@ Relationships, etc.</p>
6097
6027
 
6098
6028
  <details class="quote">
6099
6029
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
6100
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-213">213</a></span>
6030
+ <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-212">212</a></span>
6031
+ <span class="normal"><a href="#__codelineno-0-213">213</a></span>
6101
6032
  <span class="normal"><a href="#__codelineno-0-214">214</a></span>
6102
6033
  <span class="normal"><a href="#__codelineno-0-215">215</a></span>
6103
6034
  <span class="normal"><a href="#__codelineno-0-216">216</a></span>
@@ -6145,57 +6076,56 @@ Relationships, etc.</p>
6145
6076
  <span class="normal"><a href="#__codelineno-0-258">258</a></span>
6146
6077
  <span class="normal"><a href="#__codelineno-0-259">259</a></span>
6147
6078
  <span class="normal"><a href="#__codelineno-0-260">260</a></span>
6148
- <span class="normal"><a href="#__codelineno-0-261">261</a></span>
6149
- <span class="normal"><a href="#__codelineno-0-262">262</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="nd">@classmethod</span>
6150
- <a id="__codelineno-0-214" name="__codelineno-0-214"></a><span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">user_config</span><span class="p">,</span> <span class="n">nautobot_version</span><span class="p">):</span>
6151
- <a id="__codelineno-0-215" name="__codelineno-0-215"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
6152
- <a id="__codelineno-0-216" name="__codelineno-0-216"></a>
6153
- <a id="__codelineno-0-217" name="__codelineno-0-217"></a> <span class="n">plugin_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span>
6154
- <a id="__codelineno-0-218" name="__codelineno-0-218"></a>
6155
- <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="c1"># Enforce version constraints</span>
6156
- <a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="n">current_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">nautobot_version</span><span class="p">)</span>
6157
- <a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6158
- <a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="p">)</span>
6159
- <a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&lt;</span> <span class="n">min_version</span><span class="p">:</span>
6160
- <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6161
- <a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot minimum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="si">}</span><span class="s2">&quot;</span>
6162
- <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="p">)</span>
6163
- <a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6164
- <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="p">)</span>
6165
- <a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&gt;</span> <span class="n">max_version</span><span class="p">:</span>
6166
- <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6167
- <a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot maximum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="si">}</span><span class="s2">&quot;</span>
6168
- <a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="p">)</span>
6169
- <a id="__codelineno-0-233" name="__codelineno-0-233"></a>
6170
- <a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
6171
- <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
6172
- <a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
6173
- <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
6174
- <a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
6175
- <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6176
- <a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6177
- <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6178
- <a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="p">}</span>
6179
- <a id="__codelineno-0-243" name="__codelineno-0-243"></a>
6180
- <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># Validate user settings</span>
6181
- <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">for</span> <span class="n">setting_name</span><span class="p">,</span> <span class="n">setting_type</span> <span class="ow">in</span> <span class="n">setting_validations</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
6182
- <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">setting_name</span><span class="p">),</span> <span class="n">setting_type</span><span class="p">):</span>
6183
- <a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">setting_name</span><span class="si">}</span><span class="s2"> must be a </span><span class="si">{</span><span class="n">setting_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6184
- <a id="__codelineno-0-248" name="__codelineno-0-248"></a>
6185
- <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="c1"># Validate the required_settings</span>
6186
- <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">for</span> <span class="n">setting</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">required_settings</span><span class="p">:</span>
6187
- <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span><span class="p">:</span>
6188
- <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6189
- <a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires &#39;</span><span class="si">{</span><span class="n">setting</span><span class="si">}</span><span class="s2">&#39; to be present in &quot;</span>
6190
- <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="sa">f</span><span class="s2">&quot;the PLUGINS_CONFIG[&#39;</span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2">&#39;] section of your settings.&quot;</span>
6191
- <a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="p">)</span>
6192
- <a id="__codelineno-0-256" name="__codelineno-0-256"></a>
6193
- <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="c1"># Apply default configuration values</span>
6194
- <a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="k">for</span> <span class="n">setting</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">default_settings</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
6195
- <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># user_config and constance_config take precedence</span>
6196
- <a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
6197
- <a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span> <span class="ow">and</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">constance_config</span><span class="p">:</span>
6198
- <a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="n">user_config</span><span class="p">[</span><span class="n">setting</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
6079
+ <span class="normal"><a href="#__codelineno-0-261">261</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-212" name="__codelineno-0-212"></a><span class="nd">@classmethod</span>
6080
+ <a id="__codelineno-0-213" name="__codelineno-0-213"></a><span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">user_config</span><span class="p">,</span> <span class="n">nautobot_version</span><span class="p">):</span>
6081
+ <a id="__codelineno-0-214" name="__codelineno-0-214"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
6082
+ <a id="__codelineno-0-215" name="__codelineno-0-215"></a>
6083
+ <a id="__codelineno-0-216" name="__codelineno-0-216"></a> <span class="n">plugin_name</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="vm">__module__</span>
6084
+ <a id="__codelineno-0-217" name="__codelineno-0-217"></a>
6085
+ <a id="__codelineno-0-218" name="__codelineno-0-218"></a> <span class="c1"># Enforce version constraints</span>
6086
+ <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="n">current_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">nautobot_version</span><span class="p">)</span>
6087
+ <a id="__codelineno-0-220" name="__codelineno-0-220"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6088
+ <a id="__codelineno-0-221" name="__codelineno-0-221"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="p">)</span>
6089
+ <a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&lt;</span> <span class="n">min_version</span><span class="p">:</span>
6090
+ <a id="__codelineno-0-223" name="__codelineno-0-223"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6091
+ <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot minimum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">min_version</span><span class="si">}</span><span class="s2">&quot;</span>
6092
+ <a id="__codelineno-0-225" name="__codelineno-0-225"></a> <span class="p">)</span>
6093
+ <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6094
+ <a id="__codelineno-0-227" name="__codelineno-0-227"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="n">version</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="p">)</span>
6095
+ <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="k">if</span> <span class="n">current_version</span> <span class="o">&gt;</span> <span class="n">max_version</span><span class="p">:</span>
6096
+ <a id="__codelineno-0-229" name="__codelineno-0-229"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6097
+ <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires Nautobot maximum version </span><span class="si">{</span><span class="bp">cls</span><span class="o">.</span><span class="n">max_version</span><span class="si">}</span><span class="s2">&quot;</span>
6098
+ <a id="__codelineno-0-231" name="__codelineno-0-231"></a> <span class="p">)</span>
6099
+ <a id="__codelineno-0-232" name="__codelineno-0-232"></a>
6100
+ <a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
6101
+ <a id="__codelineno-0-234" name="__codelineno-0-234"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
6102
+ <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
6103
+ <a id="__codelineno-0-236" name="__codelineno-0-236"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
6104
+ <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
6105
+ <a id="__codelineno-0-238" name="__codelineno-0-238"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6106
+ <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6107
+ <a id="__codelineno-0-240" name="__codelineno-0-240"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
6108
+ <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="p">}</span>
6109
+ <a id="__codelineno-0-242" name="__codelineno-0-242"></a>
6110
+ <a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="c1"># Validate user settings</span>
6111
+ <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="k">for</span> <span class="n">setting_name</span><span class="p">,</span> <span class="n">setting_type</span> <span class="ow">in</span> <span class="n">setting_validations</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
6112
+ <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">setting_name</span><span class="p">),</span> <span class="n">setting_type</span><span class="p">):</span>
6113
+ <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">setting_name</span><span class="si">}</span><span class="s2"> must be a </span><span class="si">{</span><span class="n">setting_type</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
6114
+ <a id="__codelineno-0-247" name="__codelineno-0-247"></a>
6115
+ <a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="c1"># Validate the required_settings</span>
6116
+ <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="k">for</span> <span class="n">setting</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">required_settings</span><span class="p">:</span>
6117
+ <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span><span class="p">:</span>
6118
+ <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
6119
+ <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="sa">f</span><span class="s2">&quot;Plugin </span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2"> requires &#39;</span><span class="si">{</span><span class="n">setting</span><span class="si">}</span><span class="s2">&#39; to be present in &quot;</span>
6120
+ <a id="__codelineno-0-253" name="__codelineno-0-253"></a> <span class="sa">f</span><span class="s2">&quot;the PLUGINS_CONFIG[&#39;</span><span class="si">{</span><span class="n">plugin_name</span><span class="si">}</span><span class="s2">&#39;] section of your settings.&quot;</span>
6121
+ <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="p">)</span>
6122
+ <a id="__codelineno-0-255" name="__codelineno-0-255"></a>
6123
+ <a id="__codelineno-0-256" name="__codelineno-0-256"></a> <span class="c1"># Apply default configuration values</span>
6124
+ <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="k">for</span> <span class="n">setting</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">default_settings</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
6125
+ <a id="__codelineno-0-258" name="__codelineno-0-258"></a> <span class="c1"># user_config and constance_config take precedence</span>
6126
+ <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
6127
+ <a id="__codelineno-0-260" name="__codelineno-0-260"></a> <span class="k">if</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_config</span> <span class="ow">and</span> <span class="n">setting</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">constance_config</span><span class="p">:</span>
6128
+ <a id="__codelineno-0-261" name="__codelineno-0-261"></a> <span class="n">user_config</span><span class="p">[</span><span class="n">setting</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
6199
6129
  </code></pre></div></td></tr></table></div>
6200
6130
  </details>
6201
6131
  </div>