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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (780) hide show
  1. nautobot/apps/api.py +6 -8
  2. nautobot/apps/forms.py +0 -2
  3. nautobot/apps/ui.py +0 -8
  4. nautobot/circuits/api/serializers.py +9 -117
  5. nautobot/circuits/api/urls.py +1 -1
  6. nautobot/circuits/api/views.py +0 -1
  7. nautobot/circuits/forms.py +0 -65
  8. nautobot/circuits/migrations/0014_related_name_changes.py +1 -1
  9. nautobot/circuits/migrations/0016_tagsfield.py +34 -0
  10. nautobot/circuits/migrations/0017_fixup_null_statuses.py +22 -0
  11. nautobot/circuits/migrations/0018_status_nonnullable.py +22 -0
  12. nautobot/circuits/models.py +3 -87
  13. nautobot/circuits/navigation.py +14 -69
  14. nautobot/circuits/signals.py +0 -2
  15. nautobot/circuits/tables.py +39 -1
  16. nautobot/circuits/tests/integration/test_relationships.py +9 -9
  17. nautobot/circuits/tests/test_api.py +4 -8
  18. nautobot/circuits/tests/test_filters.py +10 -4
  19. nautobot/circuits/tests/test_models.py +5 -1
  20. nautobot/circuits/tests/test_views.py +27 -5
  21. nautobot/circuits/views.py +18 -10
  22. nautobot/core/api/__init__.py +8 -2
  23. nautobot/core/api/fields.py +15 -6
  24. nautobot/core/api/filter_backends.py +3 -2
  25. nautobot/core/api/metadata.py +237 -30
  26. nautobot/core/api/mixins.py +94 -0
  27. nautobot/core/api/pagination.py +4 -0
  28. nautobot/core/api/parsers.py +154 -0
  29. nautobot/core/api/renderers.py +153 -2
  30. nautobot/core/api/schema.py +46 -2
  31. nautobot/core/api/serializers.py +377 -35
  32. nautobot/core/api/urls.py +11 -3
  33. nautobot/core/api/utils.py +174 -2
  34. nautobot/core/api/versioning.py +32 -10
  35. nautobot/core/api/views.py +266 -72
  36. nautobot/core/apps/__init__.py +138 -220
  37. nautobot/core/celery/__init__.py +112 -41
  38. nautobot/core/celery/backends.py +19 -12
  39. nautobot/core/celery/control.py +46 -0
  40. nautobot/core/celery/encoders.py +53 -0
  41. nautobot/core/celery/log.py +38 -0
  42. nautobot/core/celery/schedulers.py +23 -4
  43. nautobot/core/celery/task.py +1 -16
  44. nautobot/core/checks.py +0 -27
  45. nautobot/core/choices.py +0 -113
  46. nautobot/core/{cli.py → cli/__init__.py} +1 -1
  47. nautobot/core/cli/__main__.py +3 -0
  48. nautobot/core/constants.py +0 -24
  49. nautobot/core/context_processors.py +12 -0
  50. nautobot/core/filters.py +2 -2
  51. nautobot/core/forms/__init__.py +0 -4
  52. nautobot/core/forms/fields.py +38 -65
  53. nautobot/core/forms/forms.py +4 -1
  54. nautobot/core/forms/utils.py +0 -52
  55. nautobot/core/graphql/schema.py +4 -27
  56. nautobot/core/jobs/__init__.py +75 -0
  57. nautobot/core/management/commands/build_ui.py +255 -0
  58. nautobot/core/management/commands/generate_test_data.py +3 -2
  59. nautobot/core/management/commands/post_upgrade.py +24 -24
  60. nautobot/core/models/__init__.py +26 -1
  61. nautobot/core/models/fields.py +24 -5
  62. nautobot/core/models/generics.py +2 -42
  63. nautobot/core/models/managers.py +5 -0
  64. nautobot/core/models/name_color_content_types.py +0 -14
  65. nautobot/core/models/tree_queries.py +14 -4
  66. nautobot/core/models/utils.py +5 -6
  67. nautobot/core/models/validators.py +17 -8
  68. nautobot/core/releases.py +8 -10
  69. nautobot/core/settings.py +80 -42
  70. nautobot/core/tables.py +5 -5
  71. nautobot/core/tasks.py +4 -7
  72. nautobot/core/templates/base.html +1 -49
  73. nautobot/core/templates/base_django.html +49 -0
  74. nautobot/core/templates/base_react.html +55 -0
  75. nautobot/core/templates/buttons/export.html +6 -4
  76. nautobot/core/templates/generic/object_bulk_create.html +10 -21
  77. nautobot/core/templates/generic/object_list.html +3 -1
  78. nautobot/core/templates/generic/object_retrieve_plugin_full_width.html +3 -0
  79. nautobot/core/templates/inc/footer.html +1 -0
  80. nautobot/core/templates/inc/javascript.html +0 -14
  81. nautobot/core/templates/inc/nav_menu.html +28 -33
  82. nautobot/core/templates/inc/object_details_advanced_panel.html +13 -0
  83. nautobot/core/templates/inc/relationships_table_rows.html +2 -2
  84. nautobot/core/templates/nautobot_config.py.j2 +8 -20
  85. nautobot/core/templates/plugin_template/__init__.py-tpl +1 -2
  86. nautobot/core/templates/rest_framework/api.html +8 -0
  87. nautobot/core/templatetags/buttons.py +32 -28
  88. nautobot/core/testing/__init__.py +47 -44
  89. nautobot/core/testing/api.py +362 -47
  90. nautobot/core/testing/filters.py +1 -1
  91. nautobot/core/testing/migrations.py +2 -0
  92. nautobot/core/testing/mixins.py +22 -9
  93. nautobot/core/testing/schema.py +2 -1
  94. nautobot/core/testing/views.py +21 -46
  95. nautobot/core/tests/integration/test_filters.py +17 -8
  96. nautobot/core/tests/integration/test_navbar.py +11 -34
  97. nautobot/core/tests/integration/test_plugin_navbar.py +9 -103
  98. nautobot/core/tests/nautobot_config.py +2 -3
  99. nautobot/core/tests/test_api.py +290 -21
  100. nautobot/core/tests/test_checks.py +0 -7
  101. nautobot/core/tests/test_filters.py +107 -59
  102. nautobot/core/tests/test_forms.py +26 -92
  103. nautobot/core/tests/test_graphql.py +110 -77
  104. nautobot/core/tests/test_logging.py +4 -0
  105. nautobot/core/tests/test_managers.py +3 -1
  106. nautobot/core/tests/test_models.py +2 -0
  107. nautobot/core/tests/test_paginator.py +3 -1
  108. nautobot/core/tests/test_releases.py +12 -12
  109. nautobot/core/tests/test_templatetags_helpers.py +4 -4
  110. nautobot/core/tests/test_utils.py +32 -68
  111. nautobot/core/tests/test_views.py +12 -15
  112. nautobot/core/utils/data.py +17 -0
  113. nautobot/core/utils/deprecation.py +9 -6
  114. nautobot/core/utils/filtering.py +8 -3
  115. nautobot/core/utils/git.py +12 -4
  116. nautobot/core/utils/lookup.py +3 -1
  117. nautobot/core/utils/requests.py +1 -104
  118. nautobot/core/views/__init__.py +1 -0
  119. nautobot/core/views/generic.py +75 -110
  120. nautobot/core/views/mixins.py +52 -61
  121. nautobot/core/views/renderers.py +6 -7
  122. nautobot/core/views/utils.py +80 -0
  123. nautobot/dcim/api/serializers.py +160 -667
  124. nautobot/dcim/api/urls.py +1 -1
  125. nautobot/dcim/api/views.py +7 -44
  126. nautobot/dcim/choices.py +2 -0
  127. nautobot/dcim/filters/__init__.py +21 -0
  128. nautobot/dcim/form_mixins.py +1 -27
  129. nautobot/dcim/forms.py +19 -765
  130. nautobot/dcim/migrations/0024_alter_device_and_rack_role_add_new_role.py +2 -1
  131. nautobot/dcim/migrations/0025_device_and_rack_roles_data_migrations.py +19 -13
  132. nautobot/dcim/migrations/0027_remove_device_role_and_rack_role.py +1 -1
  133. nautobot/dcim/migrations/0028_rename_foreignkey_fields.py +1 -1
  134. nautobot/dcim/migrations/0030_migrate_region_and_site_data_to_locations.py +2 -2
  135. nautobot/dcim/migrations/0035_related_name_changes.py +1 -1
  136. nautobot/dcim/migrations/0036_remove_region_and_site.py +1 -1
  137. nautobot/dcim/migrations/0040_tagsfield.py +109 -0
  138. nautobot/dcim/migrations/{0040_ipam__namespaces.py → 0041_ipam__namespaces.py} +1 -1
  139. nautobot/dcim/migrations/0042_fixup_null_statuses.py +51 -0
  140. nautobot/dcim/migrations/0043_status_nonnullable.py +72 -0
  141. nautobot/dcim/models/cables.py +3 -33
  142. nautobot/dcim/models/device_component_templates.py +6 -0
  143. nautobot/dcim/models/device_components.py +12 -198
  144. nautobot/dcim/models/devices.py +30 -143
  145. nautobot/dcim/models/locations.py +3 -64
  146. nautobot/dcim/models/power.py +3 -50
  147. nautobot/dcim/models/racks.py +7 -84
  148. nautobot/dcim/navigation.py +141 -467
  149. nautobot/dcim/signals.py +0 -2
  150. nautobot/dcim/tables/locations.py +2 -2
  151. nautobot/dcim/tables/power.py +1 -2
  152. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -0
  153. nautobot/dcim/templates/dcim/devicetype.html +2 -2
  154. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -0
  155. nautobot/dcim/templates/dcim/location.html +16 -1
  156. nautobot/dcim/templates/dcim/locationtype.html +15 -0
  157. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -0
  158. nautobot/dcim/templates/dcim/rackgroup.html +0 -12
  159. nautobot/dcim/tests/test_api.py +166 -81
  160. nautobot/dcim/tests/test_cablepaths.py +41 -35
  161. nautobot/dcim/tests/test_filters.py +67 -23
  162. nautobot/dcim/tests/test_forms.py +5 -205
  163. nautobot/dcim/tests/test_graphql.py +7 -2
  164. nautobot/dcim/tests/test_migrations.py +6 -11
  165. nautobot/dcim/tests/test_models.py +182 -110
  166. nautobot/dcim/tests/test_natural_ordering.py +11 -8
  167. nautobot/dcim/tests/test_signals.py +6 -3
  168. nautobot/dcim/tests/test_views.py +197 -175
  169. nautobot/dcim/urls.py +11 -16
  170. nautobot/dcim/views.py +7 -134
  171. nautobot/docs/additional-features/caching.md +6 -87
  172. nautobot/docs/additional-features/job-scheduling-and-approvals.md +3 -0
  173. nautobot/docs/additional-features/jobs.md +177 -195
  174. nautobot/docs/administration/nautobot-server.md +6 -21
  175. nautobot/docs/administration/replicating-nautobot.md +0 -10
  176. nautobot/docs/configuration/optional-settings.md +32 -41
  177. nautobot/docs/configuration/required-settings.md +11 -52
  178. nautobot/docs/development/application-registry.md +2 -13
  179. nautobot/docs/development/extending-models.md +15 -17
  180. nautobot/docs/development/generic-views.md +0 -2
  181. nautobot/docs/development/getting-started.md +55 -5
  182. nautobot/docs/development/navigation-menu.md +22 -93
  183. nautobot/docs/development/react-ui.md +105 -0
  184. nautobot/docs/development/role-internals.md +1 -3
  185. nautobot/docs/development/style-guide.md +6 -4
  186. nautobot/docs/index.md +3 -2
  187. nautobot/docs/installation/migrating-from-netbox.md +11 -42
  188. nautobot/docs/installation/nautobot.md +1 -1
  189. nautobot/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
  190. nautobot/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
  191. nautobot/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
  192. nautobot/docs/installation/tables/v2-code-location-changes.yaml +241 -0
  193. nautobot/docs/installation/tables/v2-code-removals.yaml +67 -0
  194. nautobot/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
  195. nautobot/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
  196. nautobot/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
  197. nautobot/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
  198. nautobot/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
  199. nautobot/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
  200. nautobot/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
  201. nautobot/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
  202. nautobot/docs/installation/upgrading-from-nautobot-v1.md +170 -747
  203. nautobot/docs/models/dcim/device.md +3 -0
  204. nautobot/docs/models/dcim/deviceredundancygroup.md +3 -3
  205. nautobot/docs/models/extras/computedfield.md +4 -4
  206. nautobot/docs/models/extras/gitrepository.md +3 -0
  207. nautobot/docs/models/extras/job.md +1 -0
  208. nautobot/docs/models/extras/jobbutton.md +18 -13
  209. nautobot/docs/models/extras/jobhook.md +7 -4
  210. nautobot/docs/models/extras/jobresult.md +6 -2
  211. nautobot/docs/models/extras/relationship.md +2 -2
  212. nautobot/docs/models/extras/status.md +6 -19
  213. nautobot/docs/models/ipam/ipaddress.md +3 -0
  214. nautobot/docs/models/virtualization/virtualmachine.md +3 -0
  215. nautobot/docs/plugins/development.md +83 -21
  216. nautobot/docs/release-notes/version-1.5.md +53 -0
  217. nautobot/docs/release-notes/version-2.0.md +180 -0
  218. nautobot/docs/requirements.txt +1 -0
  219. nautobot/docs/rest-api/overview.md +384 -215
  220. nautobot/docs/rest-api/ui-related-endpoints.md +9 -0
  221. nautobot/extras/admin.py +3 -5
  222. nautobot/extras/api/customfields.py +15 -39
  223. nautobot/extras/api/fields.py +0 -11
  224. nautobot/extras/api/mixins.py +45 -0
  225. nautobot/extras/api/relationships.py +63 -158
  226. nautobot/extras/api/serializers.py +165 -700
  227. nautobot/extras/api/urls.py +1 -1
  228. nautobot/extras/api/views.py +294 -280
  229. nautobot/extras/apps.py +4 -7
  230. nautobot/extras/choices.py +11 -9
  231. nautobot/extras/constants.py +9 -3
  232. nautobot/extras/datasources/__init__.py +2 -0
  233. nautobot/extras/datasources/git.py +135 -186
  234. nautobot/extras/datasources/registry.py +25 -35
  235. nautobot/extras/filters/__init__.py +20 -19
  236. nautobot/extras/filters/mixins.py +4 -4
  237. nautobot/extras/forms/forms.py +63 -127
  238. nautobot/extras/forms/mixins.py +23 -51
  239. nautobot/extras/health_checks.py +0 -33
  240. nautobot/extras/jobs.py +387 -565
  241. nautobot/extras/management/commands/runjob.py +24 -62
  242. nautobot/extras/managers.py +30 -7
  243. nautobot/extras/migrations/0058_jobresult_add_time_status_idxs.py +38 -0
  244. nautobot/extras/migrations/{0058_joblogentry_scheduledjob_webhook_data_migration.py → 0059_joblogentry_scheduledjob_webhook_data_migration.py} +1 -1
  245. nautobot/extras/migrations/{0059_alter_joblogentry_scheduledjob_webhook_fields.py → 0060_alter_joblogentry_scheduledjob_webhook_fields.py} +1 -1
  246. nautobot/extras/migrations/{0060_role_and_alter_status.py → 0061_role_and_alter_status.py} +1 -7
  247. nautobot/extras/migrations/{0061_collect_roles_from_related_apps_roles.py → 0062_collect_roles_from_related_apps_roles.py} +33 -32
  248. nautobot/extras/migrations/{0062_alter_role_options.py → 0063_alter_role_options.py} +1 -1
  249. nautobot/extras/migrations/{0063_alter_configcontext_and_add_new_role.py → 0064_alter_configcontext_and_add_new_role.py} +1 -1
  250. nautobot/extras/migrations/0065_configcontext_data_migrations.py +44 -0
  251. nautobot/extras/migrations/{0065_rename_configcontext_role.py → 0066_rename_configcontext_role.py} +1 -1
  252. nautobot/extras/migrations/{0066_jobresult__add_celery_fields.py → 0067_jobresult__add_celery_fields.py} +36 -2
  253. nautobot/extras/migrations/{0067_created_datetime.py → 0068_created_datetime.py} +1 -1
  254. nautobot/extras/migrations/{0068_remove_site_and_region_attributes_from_config_context.py → 0069_remove_site_and_region_attributes_from_config_context.py} +1 -1
  255. nautobot/extras/migrations/{0069_replace_related_names.py → 0070_replace_related_names.py} +1 -1
  256. nautobot/extras/migrations/{0070_rename_model_fields.py → 0071_rename_model_fields.py} +1 -1
  257. nautobot/extras/migrations/0072_job__unique_name_data_migration.py +86 -0
  258. nautobot/extras/migrations/{0072_job__unique_name.py → 0073_job__unique_name.py} +13 -9
  259. nautobot/extras/migrations/{0073_remove_gitrepository_fields.py → 0074_remove_gitrepository_fields.py} +1 -1
  260. nautobot/extras/migrations/{0074_rename_slug_to_key_for_custom_field.py → 0075_rename_slug_to_key_for_custom_field.py} +1 -1
  261. nautobot/extras/migrations/{0075_migrate_custom_field_data.py → 0076_migrate_custom_field_data.py} +1 -1
  262. nautobot/extras/migrations/{0076_remove_name_field_and_make_label_field_non_nullable.py → 0077_remove_name_field_and_make_label_field_non_nullable.py} +1 -1
  263. nautobot/extras/migrations/{0077_remove_slug.py → 0078_remove_slug.py} +1 -5
  264. nautobot/extras/migrations/0079_tagsfield.py +28 -0
  265. nautobot/extras/migrations/0080_rename_relationship_slug_to_key.py +17 -0
  266. nautobot/extras/migrations/0081_rename_relationship_name_to_label.py +29 -0
  267. nautobot/extras/migrations/0082_ensure_relationship_keys_are_unique.py +43 -0
  268. nautobot/extras/migrations/0083_rename_computed_field_slug_to_key.py +21 -0
  269. nautobot/extras/migrations/0084_taggeditem_cleanup.py +43 -0
  270. nautobot/extras/migrations/0085_taggeditem_uniqueness.py +22 -0
  271. nautobot/extras/migrations/0086_job__celery_task_fields__dryrun_support.py +81 -0
  272. nautobot/extras/migrations/0087_job__commit_default_data_migration.py +26 -0
  273. nautobot/extras/migrations/0088_joblogentry__log_level_default.py +17 -0
  274. nautobot/extras/migrations/0089_joblogentry__log_level_data_migration.py +34 -0
  275. nautobot/extras/migrations/0090_scheduledjob__data_migration.py +57 -0
  276. nautobot/extras/models/__init__.py +2 -3
  277. nautobot/extras/models/change_logging.py +0 -36
  278. nautobot/extras/models/customfields.py +39 -33
  279. nautobot/extras/models/datasources.py +48 -50
  280. nautobot/extras/models/groups.py +5 -6
  281. nautobot/extras/models/jobs.py +189 -321
  282. nautobot/extras/models/mixins.py +0 -71
  283. nautobot/extras/models/models.py +0 -19
  284. nautobot/extras/models/relationships.py +19 -13
  285. nautobot/extras/models/roles.py +0 -34
  286. nautobot/extras/models/secrets.py +2 -26
  287. nautobot/extras/models/statuses.py +6 -5
  288. nautobot/extras/models/tags.py +2 -17
  289. nautobot/extras/navigation.py +89 -307
  290. nautobot/extras/plugins/__init__.py +3 -120
  291. nautobot/extras/plugins/utils.py +0 -3
  292. nautobot/extras/plugins/validators.py +5 -4
  293. nautobot/extras/plugins/views.py +16 -3
  294. nautobot/extras/querysets.py +1 -7
  295. nautobot/extras/registry.py +3 -0
  296. nautobot/extras/signals.py +26 -60
  297. nautobot/extras/tables.py +34 -40
  298. nautobot/extras/tasks.py +0 -12
  299. nautobot/extras/templates/extras/configcontext.html +1 -1
  300. nautobot/extras/templates/extras/configcontextschema.html +16 -1
  301. nautobot/extras/templates/extras/customfield.html +0 -13
  302. nautobot/extras/templates/extras/gitrepository.html +3 -3
  303. nautobot/extras/templates/extras/inc/jobresult.html +10 -0
  304. nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
  305. nautobot/extras/templates/extras/job.html +35 -25
  306. nautobot/extras/templates/extras/job_approval_request.html +15 -30
  307. nautobot/extras/templates/extras/job_detail.html +13 -31
  308. nautobot/extras/templates/extras/job_edit.html +15 -17
  309. nautobot/extras/templates/extras/jobresult.html +24 -6
  310. nautobot/extras/templates/extras/scheduledjob.html +2 -2
  311. nautobot/extras/templates/extras/secret.html +28 -0
  312. nautobot/extras/templatetags/job_buttons.py +1 -0
  313. nautobot/extras/{tests/example_jobs → test_jobs}/api_test_job.py +13 -6
  314. nautobot/extras/test_jobs/atomic_transaction.py +53 -0
  315. nautobot/extras/test_jobs/dry_run.py +29 -0
  316. nautobot/extras/{tests/example_jobs/test_duplicate_name.py → test_jobs/duplicate_name.py} +4 -0
  317. nautobot/extras/test_jobs/duplicate_name2.py +9 -0
  318. nautobot/extras/test_jobs/fail.py +23 -0
  319. nautobot/extras/{tests/example_jobs/test_field_default.py → test_jobs/field_default.py} +4 -0
  320. nautobot/extras/{tests/example_jobs/test_field_order.py → test_jobs/field_order.py} +4 -0
  321. nautobot/extras/{tests/example_jobs/test_file_upload_fail.py → test_jobs/file_upload_fail.py} +11 -6
  322. nautobot/extras/test_jobs/file_upload_pass.py +25 -0
  323. nautobot/extras/test_jobs/has_sensitive_variables.py +25 -0
  324. nautobot/extras/test_jobs/ipaddress_vars.py +66 -0
  325. nautobot/extras/test_jobs/job_button_receiver.py +28 -0
  326. nautobot/extras/test_jobs/job_hook_receiver.py +29 -0
  327. nautobot/extras/test_jobs/job_variables.py +88 -0
  328. nautobot/extras/test_jobs/location_with_custom_field.py +45 -0
  329. nautobot/extras/test_jobs/log_redaction.py +20 -0
  330. nautobot/extras/test_jobs/log_skip_db_logging.py +17 -0
  331. nautobot/extras/test_jobs/modify_db.py +25 -0
  332. nautobot/extras/{tests/example_jobs/test_no_field_order.py → test_jobs/no_field_order.py} +4 -0
  333. nautobot/extras/test_jobs/object_var_optional.py +21 -0
  334. nautobot/extras/test_jobs/object_var_required.py +21 -0
  335. nautobot/extras/test_jobs/object_vars.py +26 -0
  336. nautobot/extras/test_jobs/pass.py +25 -0
  337. nautobot/extras/test_jobs/profiling.py +32 -0
  338. nautobot/extras/test_jobs/read_only_job.py +15 -0
  339. nautobot/extras/{tests/example_jobs/test_required_args.py → test_jobs/required_args.py} +4 -0
  340. nautobot/extras/{tests/example_jobs/test_soft_time_limit_greater_than_time_limit.py → test_jobs/soft_time_limit_greater_than_time_limit.py} +5 -1
  341. nautobot/extras/{tests/example_jobs/test_task_queues.py → test_jobs/task_queues.py} +5 -1
  342. nautobot/extras/tests/integration/test_computedfields.py +1 -1
  343. nautobot/extras/tests/integration/test_configcontextschema.py +5 -3
  344. nautobot/extras/tests/integration/test_customfields.py +4 -2
  345. nautobot/extras/tests/integration/test_dynamicgroups.py +1 -1
  346. nautobot/extras/tests/integration/test_jobs.py +25 -27
  347. nautobot/extras/tests/integration/test_notes.py +8 -4
  348. nautobot/extras/tests/integration/test_relationships.py +2 -2
  349. nautobot/extras/tests/test_api.py +649 -642
  350. nautobot/extras/tests/test_changelog.py +3 -3
  351. nautobot/extras/tests/test_context_managers.py +5 -3
  352. nautobot/extras/tests/test_customfields.py +92 -50
  353. nautobot/extras/tests/test_datasources.py +189 -112
  354. nautobot/extras/tests/test_dynamicgroups.py +7 -8
  355. nautobot/extras/tests/test_filters.py +137 -89
  356. nautobot/extras/tests/test_forms.py +73 -75
  357. nautobot/extras/tests/{test_scripts.py → test_job_variables.py} +43 -49
  358. nautobot/extras/tests/test_jobs.py +262 -263
  359. nautobot/extras/tests/test_migrations.py +4 -3
  360. nautobot/extras/tests/test_models.py +116 -161
  361. nautobot/extras/tests/test_plugins.py +38 -60
  362. nautobot/extras/tests/test_relationships.py +167 -120
  363. nautobot/extras/tests/test_tags.py +6 -11
  364. nautobot/extras/tests/test_utils.py +31 -1
  365. nautobot/extras/tests/test_views.py +201 -145
  366. nautobot/extras/tests/test_webhooks.py +6 -2
  367. nautobot/extras/urls.py +42 -42
  368. nautobot/extras/utils.py +137 -163
  369. nautobot/extras/views.py +78 -152
  370. nautobot/ipam/api/fields.py +17 -0
  371. nautobot/ipam/api/serializers.py +58 -164
  372. nautobot/ipam/api/urls.py +1 -1
  373. nautobot/ipam/api/views.py +3 -2
  374. nautobot/ipam/apps.py +1 -2
  375. nautobot/ipam/filters.py +1 -10
  376. nautobot/ipam/forms.py +4 -177
  377. nautobot/ipam/lookups.py +1 -0
  378. nautobot/ipam/management/commands/__init__.py +0 -0
  379. nautobot/ipam/management/commands/fix_prefix_broadcast.py +17 -0
  380. nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -1
  381. nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +32 -38
  382. nautobot/ipam/migrations/0020_related_name_changes.py +1 -1
  383. nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +2 -2
  384. nautobot/ipam/migrations/0028_tagsfield.py +44 -0
  385. nautobot/ipam/migrations/0029_ip_address_to_interface_uniqueness_constraints.py +18 -0
  386. nautobot/ipam/migrations/{0028_ipam__namespaces.py → 0030_ipam__namespaces.py} +77 -28
  387. nautobot/ipam/migrations/0031_ipam__prefix__add_parent.py +58 -0
  388. nautobot/ipam/migrations/0032_ipam__namespaces_finish.py +63 -0
  389. nautobot/ipam/migrations/0033_fixup_null_statuses.py +26 -0
  390. nautobot/ipam/migrations/0034_status_nonnullable.py +36 -0
  391. nautobot/ipam/models.py +100 -236
  392. nautobot/ipam/navigation.py +36 -181
  393. nautobot/ipam/querysets.py +20 -25
  394. nautobot/ipam/signals.py +49 -6
  395. nautobot/ipam/tables.py +10 -3
  396. nautobot/ipam/templates/ipam/namespace_ipaddresses.html +11 -0
  397. nautobot/ipam/templates/ipam/namespace_prefixes.html +11 -0
  398. nautobot/ipam/templates/ipam/namespace_retrieve.html +17 -4
  399. nautobot/ipam/templates/ipam/namespace_vrfs.html +11 -0
  400. nautobot/ipam/templates/ipam/prefix.html +1 -1
  401. nautobot/ipam/templates/ipam/vlangroup.html +0 -13
  402. nautobot/ipam/templates/ipam/vrf_edit.html +6 -0
  403. nautobot/ipam/tests/integration/test_prefixes.py +3 -26
  404. nautobot/ipam/tests/test_api.py +22 -19
  405. nautobot/ipam/tests/test_filters.py +59 -23
  406. nautobot/ipam/tests/test_migrations.py +6 -10
  407. nautobot/ipam/tests/test_models.py +323 -198
  408. nautobot/ipam/tests/test_ordering.py +2 -2
  409. nautobot/ipam/tests/test_querysets.py +44 -24
  410. nautobot/ipam/tests/test_views.py +73 -26
  411. nautobot/ipam/urls.py +16 -0
  412. nautobot/ipam/{utils.py → utils/__init__.py} +2 -2
  413. nautobot/ipam/utils/migrations.py +713 -0
  414. nautobot/ipam/views.py +137 -20
  415. nautobot/project-static/docs/404.html +1178 -10
  416. nautobot/project-static/docs/additional-features/caching.html +1224 -159
  417. nautobot/project-static/docs/additional-features/change-logging.html +1180 -12
  418. nautobot/project-static/docs/additional-features/config-contexts.html +1180 -12
  419. nautobot/project-static/docs/additional-features/graphql.html +1179 -11
  420. nautobot/project-static/docs/additional-features/healthcheck.html +1180 -12
  421. nautobot/project-static/docs/additional-features/job-scheduling-and-approvals.html +1184 -12
  422. nautobot/project-static/docs/additional-features/jobs.html +1514 -328
  423. nautobot/project-static/docs/additional-features/napalm.html +1180 -12
  424. nautobot/project-static/docs/additional-features/prometheus-metrics.html +1180 -12
  425. nautobot/project-static/docs/additional-features/template-filters.html +1180 -12
  426. nautobot/project-static/docs/administration/celery-queues.html +1178 -10
  427. nautobot/project-static/docs/administration/nautobot-server.html +1451 -304
  428. nautobot/project-static/docs/administration/nautobot-shell.html +1178 -10
  429. nautobot/project-static/docs/administration/permissions.html +1178 -10
  430. nautobot/project-static/docs/administration/replicating-nautobot.html +1262 -113
  431. nautobot/project-static/docs/apps/index.html +1178 -10
  432. nautobot/project-static/docs/apps/nautobot-apps.html +1178 -10
  433. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +1580 -426
  434. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +1178 -10
  435. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +3481 -1838
  436. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +1178 -10
  437. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +1178 -10
  438. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +1185 -11
  439. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1719 -551
  440. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2062 -930
  441. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1946 -659
  442. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +1180 -12
  443. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1189 -21
  444. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +9283 -6218
  445. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2734 -2122
  446. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +1178 -10
  447. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2337 -1300
  448. nautobot/project-static/docs/configuration/authentication/ldap.html +1178 -10
  449. nautobot/project-static/docs/configuration/authentication/remote.html +1178 -10
  450. nautobot/project-static/docs/configuration/authentication/sso.html +1178 -10
  451. nautobot/project-static/docs/configuration/index.html +1178 -10
  452. nautobot/project-static/docs/configuration/optional-settings.html +1311 -160
  453. nautobot/project-static/docs/configuration/required-settings.html +1312 -211
  454. nautobot/project-static/docs/core-functionality/circuits.html +1178 -10
  455. nautobot/project-static/docs/core-functionality/device-types.html +1178 -10
  456. nautobot/project-static/docs/core-functionality/devices.html +1182 -10
  457. nautobot/project-static/docs/core-functionality/ipam.html +1182 -10
  458. nautobot/project-static/docs/core-functionality/power.html +1178 -10
  459. nautobot/project-static/docs/core-functionality/secrets.html +1178 -10
  460. nautobot/project-static/docs/core-functionality/services.html +1178 -10
  461. nautobot/project-static/docs/core-functionality/sites-and-racks.html +1178 -10
  462. nautobot/project-static/docs/core-functionality/tenancy.html +1178 -10
  463. nautobot/project-static/docs/core-functionality/virtualization.html +1182 -10
  464. nautobot/project-static/docs/core-functionality/vlans.html +1179 -11
  465. nautobot/project-static/docs/development/application-registry.html +1190 -42
  466. nautobot/project-static/docs/development/best-practices.html +1178 -10
  467. nautobot/project-static/docs/development/docker-compose-advanced-use-cases.html +1178 -10
  468. nautobot/project-static/docs/development/extending-models.html +1238 -83
  469. nautobot/project-static/docs/development/generic-views.html +1180 -14
  470. nautobot/project-static/docs/development/getting-started.html +1365 -90
  471. nautobot/project-static/docs/development/homepage.html +1178 -10
  472. nautobot/project-static/docs/development/index.html +1178 -10
  473. nautobot/project-static/docs/development/model-features.html +1178 -10
  474. nautobot/project-static/docs/development/natural-keys.html +1178 -10
  475. nautobot/project-static/docs/development/navigation-menu.html +1215 -125
  476. nautobot/project-static/docs/development/react-ui.html +4199 -0
  477. nautobot/project-static/docs/development/release-checklist.html +1178 -10
  478. nautobot/project-static/docs/development/role-internals.html +1179 -12
  479. nautobot/project-static/docs/development/style-guide.html +1188 -19
  480. nautobot/project-static/docs/development/templates.html +1178 -10
  481. nautobot/project-static/docs/development/testing.html +1178 -10
  482. nautobot/project-static/docs/development/user-preferences.html +1178 -10
  483. nautobot/project-static/docs/docker/index.html +1178 -10
  484. nautobot/project-static/docs/index.html +1183 -12
  485. nautobot/project-static/docs/installation/centos.html +1178 -10
  486. nautobot/project-static/docs/installation/external-authentication.html +1178 -10
  487. nautobot/project-static/docs/installation/http-server.html +1178 -10
  488. nautobot/project-static/docs/installation/index.html +1178 -10
  489. nautobot/project-static/docs/installation/migrating-from-netbox.html +1305 -189
  490. nautobot/project-static/docs/installation/migrating-from-postgresql.html +1178 -10
  491. nautobot/project-static/docs/installation/nautobot.html +1179 -11
  492. nautobot/project-static/docs/installation/region-and-site-data-migration-guide.html +1178 -10
  493. nautobot/project-static/docs/installation/selinux-troubleshooting.html +1178 -10
  494. nautobot/project-static/docs/installation/services.html +1178 -10
  495. nautobot/project-static/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
  496. nautobot/project-static/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
  497. nautobot/project-static/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
  498. nautobot/project-static/docs/installation/tables/v2-code-location-changes.yaml +241 -0
  499. nautobot/project-static/docs/installation/tables/v2-code-removals.yaml +67 -0
  500. nautobot/project-static/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
  501. nautobot/project-static/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
  502. nautobot/project-static/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
  503. nautobot/project-static/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
  504. nautobot/project-static/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
  505. nautobot/project-static/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
  506. nautobot/project-static/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
  507. nautobot/project-static/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
  508. nautobot/project-static/docs/installation/ubuntu.html +1178 -10
  509. nautobot/project-static/docs/installation/upgrading-from-nautobot-v1.html +3823 -2152
  510. nautobot/project-static/docs/installation/upgrading.html +1178 -10
  511. nautobot/project-static/docs/models/circuits/circuit.html +1293 -103
  512. nautobot/project-static/docs/models/circuits/circuittermination.html +1293 -103
  513. nautobot/project-static/docs/models/circuits/circuittype.html +1293 -103
  514. nautobot/project-static/docs/models/circuits/provider.html +1293 -103
  515. nautobot/project-static/docs/models/circuits/providernetwork.html +1293 -103
  516. nautobot/project-static/docs/models/dcim/cable.html +1324 -103
  517. nautobot/project-static/docs/models/dcim/consoleport.html +1293 -103
  518. nautobot/project-static/docs/models/dcim/consoleporttemplate.html +1293 -103
  519. nautobot/project-static/docs/models/dcim/consoleserverport.html +1293 -103
  520. nautobot/project-static/docs/models/dcim/consoleserverporttemplate.html +1293 -103
  521. nautobot/project-static/docs/models/dcim/device.html +1326 -132
  522. nautobot/project-static/docs/models/dcim/devicebay.html +1293 -103
  523. nautobot/project-static/docs/models/dcim/devicebaytemplate.html +1293 -103
  524. nautobot/project-static/docs/models/dcim/deviceredundancygroup.html +1379 -97
  525. nautobot/project-static/docs/models/dcim/devicetype.html +1293 -103
  526. nautobot/project-static/docs/models/dcim/frontport.html +1293 -103
  527. nautobot/project-static/docs/models/dcim/frontporttemplate.html +1293 -103
  528. nautobot/project-static/docs/models/dcim/interface.html +1293 -103
  529. nautobot/project-static/docs/models/dcim/interfacetemplate.html +1293 -103
  530. nautobot/project-static/docs/models/dcim/inventoryitem.html +1293 -103
  531. nautobot/project-static/docs/models/dcim/location.html +1293 -103
  532. nautobot/project-static/docs/models/dcim/locationtype.html +1293 -103
  533. nautobot/project-static/docs/models/dcim/manufacturer.html +1292 -102
  534. nautobot/project-static/docs/models/dcim/platform.html +1272 -82
  535. nautobot/project-static/docs/models/dcim/powerfeed.html +1270 -80
  536. nautobot/project-static/docs/models/dcim/poweroutlet.html +1272 -82
  537. nautobot/project-static/docs/models/dcim/poweroutlettemplate.html +1272 -82
  538. nautobot/project-static/docs/models/dcim/powerpanel.html +1270 -80
  539. nautobot/project-static/docs/models/dcim/powerport.html +1272 -82
  540. nautobot/project-static/docs/models/dcim/powerporttemplate.html +1272 -82
  541. nautobot/project-static/docs/models/dcim/rack.html +1272 -82
  542. nautobot/project-static/docs/models/dcim/rackgroup.html +1272 -82
  543. nautobot/project-static/docs/models/dcim/rackreservation.html +1272 -82
  544. nautobot/project-static/docs/models/dcim/rearport.html +1286 -96
  545. nautobot/project-static/docs/models/dcim/rearporttemplate.html +1286 -96
  546. nautobot/project-static/docs/models/dcim/region.html +1178 -10
  547. nautobot/project-static/docs/models/dcim/site.html +1178 -10
  548. nautobot/project-static/docs/models/dcim/virtualchassis.html +1284 -94
  549. nautobot/project-static/docs/models/extras/computedfield.html +1184 -16
  550. nautobot/project-static/docs/models/extras/configcontext.html +1314 -86
  551. nautobot/project-static/docs/models/extras/configcontextschema.html +1276 -86
  552. nautobot/project-static/docs/models/extras/customfield.html +1180 -12
  553. nautobot/project-static/docs/models/extras/customlink.html +1180 -12
  554. nautobot/project-static/docs/models/extras/dynamicgroup.html +1180 -12
  555. nautobot/project-static/docs/models/extras/exporttemplate.html +1180 -12
  556. nautobot/project-static/docs/models/extras/gitrepository.html +1184 -12
  557. nautobot/project-static/docs/models/extras/graphqlquery.html +1321 -86
  558. nautobot/project-static/docs/models/extras/imageattachment.html +1276 -86
  559. nautobot/project-static/docs/models/extras/job.html +1277 -86
  560. nautobot/project-static/docs/models/extras/jobbutton.html +1201 -29
  561. nautobot/project-static/docs/models/extras/jobhook.html +1188 -16
  562. nautobot/project-static/docs/models/extras/joblogentry.html +1274 -84
  563. nautobot/project-static/docs/models/extras/jobresult.html +1364 -169
  564. nautobot/project-static/docs/models/extras/note.html +1180 -12
  565. nautobot/project-static/docs/models/extras/relationship.html +1182 -14
  566. nautobot/project-static/docs/models/extras/role.html +1320 -86
  567. nautobot/project-static/docs/models/extras/secret.html +1314 -86
  568. nautobot/project-static/docs/models/extras/secretsgroup.html +1276 -86
  569. nautobot/project-static/docs/models/extras/status.html +1188 -59
  570. nautobot/project-static/docs/models/extras/tag.html +1180 -12
  571. nautobot/project-static/docs/models/extras/webhook.html +1180 -12
  572. nautobot/project-static/docs/models/ipam/ipaddress.html +1327 -102
  573. nautobot/project-static/docs/models/ipam/prefix.html +1276 -86
  574. nautobot/project-static/docs/models/ipam/rir.html +1276 -86
  575. nautobot/project-static/docs/models/ipam/routetarget.html +1276 -86
  576. nautobot/project-static/docs/models/ipam/service.html +1276 -86
  577. nautobot/project-static/docs/models/ipam/vlan.html +1276 -86
  578. nautobot/project-static/docs/models/ipam/vlangroup.html +1276 -86
  579. nautobot/project-static/docs/models/ipam/vrf.html +1276 -86
  580. nautobot/project-static/docs/models/tenancy/tenant.html +1276 -86
  581. nautobot/project-static/docs/models/tenancy/tenantgroup.html +1276 -86
  582. nautobot/project-static/docs/models/users/objectpermission.html +1314 -86
  583. nautobot/project-static/docs/models/users/token.html +1276 -86
  584. nautobot/project-static/docs/models/virtualization/cluster.html +1276 -86
  585. nautobot/project-static/docs/models/virtualization/clustergroup.html +1276 -86
  586. nautobot/project-static/docs/models/virtualization/clustertype.html +1276 -86
  587. nautobot/project-static/docs/models/virtualization/virtualmachine.html +1321 -127
  588. nautobot/project-static/docs/models/virtualization/vminterface.html +1276 -86
  589. nautobot/project-static/docs/objects.inv +0 -0
  590. nautobot/project-static/docs/plugins/development.html +1726 -495
  591. nautobot/project-static/docs/plugins/index.html +1178 -10
  592. nautobot/project-static/docs/plugins/porting-from-netbox.html +1178 -10
  593. nautobot/project-static/docs/release-notes/index.html +1178 -10
  594. nautobot/project-static/docs/release-notes/version-1.0.html +1178 -10
  595. nautobot/project-static/docs/release-notes/version-1.1.html +1178 -10
  596. nautobot/project-static/docs/release-notes/version-1.2.html +1178 -10
  597. nautobot/project-static/docs/release-notes/version-1.3.html +1178 -10
  598. nautobot/project-static/docs/release-notes/version-1.4.html +1178 -10
  599. nautobot/project-static/docs/release-notes/version-1.5.html +1608 -225
  600. nautobot/project-static/docs/release-notes/version-2.0.html +1547 -47
  601. nautobot/project-static/docs/requirements.txt +1 -0
  602. nautobot/project-static/docs/rest-api/authentication.html +1179 -11
  603. nautobot/project-static/docs/rest-api/filtering.html +1178 -10
  604. nautobot/project-static/docs/rest-api/overview.html +1841 -446
  605. nautobot/project-static/docs/rest-api/ui-related-endpoints.html +4057 -0
  606. nautobot/project-static/docs/search/search_index.json +1 -1
  607. nautobot/project-static/docs/sitemap.xml +197 -187
  608. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  609. nautobot/project-static/docs/user-guides/custom-fields.html +1178 -10
  610. nautobot/project-static/docs/user-guides/getting-started/creating-devices.html +1178 -10
  611. nautobot/project-static/docs/user-guides/getting-started/index.html +1178 -10
  612. nautobot/project-static/docs/user-guides/getting-started/interfaces.html +1178 -10
  613. nautobot/project-static/docs/user-guides/getting-started/ipam.html +1178 -10
  614. nautobot/project-static/docs/user-guides/getting-started/platforms.html +1178 -10
  615. nautobot/project-static/docs/user-guides/getting-started/regions.html +1178 -10
  616. nautobot/project-static/docs/user-guides/getting-started/search-bar.html +1178 -10
  617. nautobot/project-static/docs/user-guides/getting-started/tenants.html +1178 -10
  618. nautobot/project-static/docs/user-guides/getting-started/vlans-and-vlan-groups.html +1178 -10
  619. nautobot/project-static/docs/user-guides/git-data-source.html +1178 -10
  620. nautobot/project-static/docs/user-guides/graphql.html +1178 -10
  621. nautobot/project-static/docs/user-guides/relationships.html +1178 -10
  622. nautobot/project-static/docs/user-guides/s3-django-storage.html +1178 -10
  623. nautobot/project-static/js/forms.js +16 -9
  624. nautobot/project-static/js/theme.js +5 -0
  625. nautobot/tenancy/api/serializers.py +4 -32
  626. nautobot/tenancy/api/urls.py +1 -1
  627. nautobot/tenancy/forms.py +0 -28
  628. nautobot/tenancy/migrations/0008_tagsfield.py +19 -0
  629. nautobot/tenancy/models.py +0 -25
  630. nautobot/tenancy/navigation.py +6 -39
  631. nautobot/tenancy/templates/tenancy/tenant.html +12 -12
  632. nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
  633. nautobot/tenancy/tests/test_api.py +1 -3
  634. nautobot/tenancy/tests/test_filters.py +10 -5
  635. nautobot/tenancy/views.py +0 -2
  636. nautobot/ui/.eslintignore +6 -0
  637. nautobot/ui/.gitignore +10 -0
  638. nautobot/ui/.prettierignore +9 -0
  639. nautobot/ui/.prettierrc +4 -0
  640. nautobot/ui/README.md +33 -0
  641. nautobot/ui/app_imports.js.j2 +7 -0
  642. nautobot/ui/craco.config.js +46 -0
  643. nautobot/ui/jsconfig-base.json +11 -0
  644. nautobot/ui/jsconfig.json +5 -0
  645. nautobot/ui/lib/nautobot-craco-alias-plugin.js +40 -0
  646. nautobot/ui/package-lock.json +21451 -0
  647. nautobot/ui/package.json +70 -0
  648. nautobot/ui/public/index.html +47 -0
  649. nautobot/ui/public/logo192.png +0 -0
  650. nautobot/ui/public/logo512.png +0 -0
  651. nautobot/ui/public/manifest.json +25 -0
  652. nautobot/ui/public/nautobot_logo.svg +131 -0
  653. nautobot/ui/public/robots.txt +3 -0
  654. nautobot/ui/src/App.js +71 -0
  655. nautobot/ui/src/components/AppFullWidthComponents.js +8 -0
  656. nautobot/ui/src/components/AppTab.js +40 -0
  657. nautobot/ui/src/components/Apps.js +60 -0
  658. nautobot/ui/src/components/HomeChangelogPanel.js +98 -0
  659. nautobot/ui/src/components/HomePanel.js +58 -0
  660. nautobot/ui/src/components/JobHistoryTable.js +78 -0
  661. nautobot/ui/src/components/Layout.js +53 -0
  662. nautobot/ui/src/components/LoadingWidget.js +25 -0
  663. nautobot/ui/src/components/Navbar.js +116 -0
  664. nautobot/ui/src/components/NotificationPopover.js +27 -0
  665. nautobot/ui/src/components/ObjectListTable.js +209 -0
  666. nautobot/ui/src/components/ReferenceDataTag.js +35 -0
  667. nautobot/ui/src/components/RouterButton.js +10 -0
  668. nautobot/ui/src/components/RouterLink.js +10 -0
  669. nautobot/ui/src/components/SidebarNav.js +147 -0
  670. nautobot/ui/src/components/Table.js +48 -0
  671. nautobot/ui/src/components/TableItem.js +71 -0
  672. nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +16 -0
  673. nautobot/ui/src/components/__tests__/AppTab.test.js +21 -0
  674. nautobot/ui/src/components/__tests__/Apps.test.js +14 -0
  675. nautobot/ui/src/components/__tests__/Layout.test.js +33 -0
  676. nautobot/ui/src/components/__tests__/Table.test.js +36 -0
  677. nautobot/ui/src/components/__tests__/TableItem.test.js +37 -0
  678. nautobot/ui/src/components/__tests__/paginator.test.js +43 -0
  679. nautobot/ui/src/components/__tests__/paginator_form.test.js +13 -0
  680. nautobot/ui/src/components/pagination.js +93 -0
  681. nautobot/ui/src/components/paginator.js +79 -0
  682. nautobot/ui/src/components/paginator_form.js +43 -0
  683. nautobot/ui/src/components/usePagination.js +57 -0
  684. nautobot/ui/src/constants/apiPath.js +10 -0
  685. nautobot/ui/src/constants/icons.js +15 -0
  686. nautobot/ui/src/constants/size.js +15 -0
  687. nautobot/ui/src/index.js +65 -0
  688. nautobot/ui/src/reportWebVitals.js +15 -0
  689. nautobot/ui/src/router.js +77 -0
  690. nautobot/ui/src/utils/api.js +131 -0
  691. nautobot/ui/src/utils/app-import.js +15 -0
  692. nautobot/ui/src/utils/color.js +15 -0
  693. nautobot/ui/src/utils/date.js +14 -0
  694. nautobot/ui/src/utils/index.js +15 -0
  695. nautobot/ui/src/utils/navigation.js +32 -0
  696. nautobot/ui/src/utils/session.js +64 -0
  697. nautobot/ui/src/utils/store.js +242 -0
  698. nautobot/ui/src/utils/string.js +6 -0
  699. nautobot/ui/src/utils/url.js +4 -0
  700. nautobot/ui/src/views/Home.js +138 -0
  701. nautobot/ui/src/views/InstalledApps.js +80 -0
  702. nautobot/ui/src/views/Login.js +48 -0
  703. nautobot/ui/src/views/Logout.js +20 -0
  704. nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +11 -0
  705. nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +107 -0
  706. nautobot/ui/src/views/__tests__/Login.test.js +15 -0
  707. nautobot/ui/src/views/generic/GenericView.js +142 -0
  708. nautobot/ui/src/views/generic/ObjectCreate.js +96 -0
  709. nautobot/ui/src/views/generic/ObjectList.js +127 -0
  710. nautobot/ui/src/views/generic/ObjectRetrieve.js +551 -0
  711. nautobot/users/admin.py +1 -1
  712. nautobot/users/api/serializers.py +51 -61
  713. nautobot/users/api/urls.py +1 -1
  714. nautobot/users/api/views.py +53 -2
  715. nautobot/users/tests/test_api.py +110 -25
  716. nautobot/virtualization/api/serializers.py +18 -130
  717. nautobot/virtualization/api/urls.py +1 -1
  718. nautobot/virtualization/api/views.py +1 -22
  719. nautobot/virtualization/forms.py +13 -99
  720. nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -1
  721. nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +18 -11
  722. nautobot/virtualization/migrations/0015_rename_foreignkey_fields.py +1 -1
  723. nautobot/virtualization/migrations/0018_related_name_changes.py +1 -1
  724. nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +39 -0
  725. nautobot/virtualization/migrations/0022_vminterface_timestamps_data_migration.py +17 -0
  726. nautobot/virtualization/migrations/{0021_ipam__namespaces.py → 0023_ipam__namespaces.py} +2 -2
  727. nautobot/virtualization/migrations/0024_fixup_null_statuses.py +25 -0
  728. nautobot/virtualization/migrations/0025_status_nonnullable.py +29 -0
  729. nautobot/virtualization/models.py +31 -123
  730. nautobot/virtualization/navigation.py +18 -99
  731. nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -1
  732. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +6 -0
  733. nautobot/virtualization/tests/test_api.py +25 -26
  734. nautobot/virtualization/tests/test_filters.py +41 -15
  735. nautobot/virtualization/tests/test_models.py +31 -7
  736. nautobot/virtualization/tests/test_views.py +42 -25
  737. nautobot/virtualization/views.py +7 -6
  738. {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/METADATA +3 -7
  739. {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/RECORD +744 -602
  740. {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/WHEEL +1 -1
  741. nautobot/circuits/api/nested_serializers.py +0 -69
  742. nautobot/core/templates/plugin_template/navigation.py-tpl +0 -22
  743. nautobot/dcim/api/nested_serializers.py +0 -356
  744. nautobot/dcim/templates/dcim/device_import.html +0 -5
  745. nautobot/dcim/templates/dcim/device_import_child.html +0 -5
  746. nautobot/dcim/templates/dcim/inc/device_import_header.html +0 -4
  747. nautobot/extras/api/nested_serializers.py +0 -353
  748. nautobot/extras/migrations/0064_configcontext_data_migrations.py +0 -41
  749. nautobot/extras/migrations/0071_job__unique_name_data_migration.py +0 -46
  750. nautobot/extras/reports.py +0 -60
  751. nautobot/extras/scripts.py +0 -72
  752. nautobot/extras/tests/example_jobs/script_variables.py +0 -67
  753. nautobot/extras/tests/example_jobs/test_duplicate_name2.py +0 -5
  754. nautobot/extras/tests/example_jobs/test_fail.py +0 -16
  755. nautobot/extras/tests/example_jobs/test_file_upload_pass.py +0 -20
  756. nautobot/extras/tests/example_jobs/test_ipaddress_vars.py +0 -52
  757. nautobot/extras/tests/example_jobs/test_job_button_receiver.py +0 -21
  758. nautobot/extras/tests/example_jobs/test_job_hook_receiver.py +0 -20
  759. nautobot/extras/tests/example_jobs/test_location_with_custom_field.py +0 -35
  760. nautobot/extras/tests/example_jobs/test_log_redaction.py +0 -14
  761. nautobot/extras/tests/example_jobs/test_modify_db.py +0 -18
  762. nautobot/extras/tests/example_jobs/test_object_var_optional.py +0 -14
  763. nautobot/extras/tests/example_jobs/test_object_var_required.py +0 -14
  764. nautobot/extras/tests/example_jobs/test_object_vars.py +0 -29
  765. nautobot/extras/tests/example_jobs/test_pass.py +0 -19
  766. nautobot/extras/tests/example_jobs/test_read_only_fail.py +0 -24
  767. nautobot/extras/tests/example_jobs/test_read_only_no_commit_field.py +0 -10
  768. nautobot/extras/tests/example_jobs/test_read_only_pass.py +0 -22
  769. nautobot/ipam/api/nested_serializers.py +0 -159
  770. nautobot/ipam/migrations/0029_ipam__prefix__add_parent.py +0 -31
  771. nautobot/ipam/migrations/0030_ipam__prefix__data_migration.py +0 -13
  772. nautobot/ipam/migrations/0031_ipam__ipaddress__add_parent.py +0 -41
  773. nautobot/ipam/migrations/0032_ipam__ipaddress__data_migration.py +0 -11
  774. nautobot/tenancy/api/nested_serializers.py +0 -31
  775. nautobot/users/api/nested_serializers.py +0 -67
  776. nautobot/virtualization/api/nested_serializers.py +0 -65
  777. /nautobot/extras/{tests/example_jobs → test_jobs}/__init__.py +0 -0
  778. /nautobot/{dcim/models/sites.py → ipam/management/__init__.py} +0 -0
  779. {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/LICENSE.txt +0 -0
  780. {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/entry_points.txt +0 -0
@@ -1346,12 +1346,1166 @@
1346
1346
 
1347
1347
 
1348
1348
  <label class="md-nav__link" for="__nav_2_8" id="__nav_2_8_label" tabindex="0">
1349
+ Model Details
1350
+ <span class="md-nav__icon md-icon"></span>
1351
+ </label>
1352
+
1353
+ <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_8_label" aria-expanded="false">
1354
+ <label class="md-nav__title" for="__nav_2_8">
1355
+ <span class="md-nav__icon md-icon"></span>
1356
+ Model Details
1357
+ </label>
1358
+ <ul class="md-nav__list" data-md-scrollfix>
1359
+
1360
+
1361
+
1362
+
1363
+
1364
+
1365
+
1366
+ <li class="md-nav__item md-nav__item--nested">
1367
+
1368
+
1369
+
1370
+
1371
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_1" >
1372
+
1373
+
1374
+
1375
+ <label class="md-nav__link" for="__nav_2_8_1" id="__nav_2_8_1_label" tabindex="0">
1376
+ Circuits
1377
+ <span class="md-nav__icon md-icon"></span>
1378
+ </label>
1379
+
1380
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_1_label" aria-expanded="false">
1381
+ <label class="md-nav__title" for="__nav_2_8_1">
1382
+ <span class="md-nav__icon md-icon"></span>
1383
+ Circuits
1384
+ </label>
1385
+ <ul class="md-nav__list" data-md-scrollfix>
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+ <li class="md-nav__item">
1393
+ <a href="../../../models/circuits/circuit.html" class="md-nav__link">
1394
+ Circuit
1395
+ </a>
1396
+ </li>
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+
1404
+
1405
+
1406
+ <li class="md-nav__item">
1407
+ <a href="../../../models/circuits/circuittermination.html" class="md-nav__link">
1408
+ Circuit Termination
1409
+ </a>
1410
+ </li>
1411
+
1412
+
1413
+
1414
+
1415
+
1416
+
1417
+
1418
+
1419
+
1420
+ <li class="md-nav__item">
1421
+ <a href="../../../models/circuits/circuittype.html" class="md-nav__link">
1422
+ Circuit Type
1423
+ </a>
1424
+ </li>
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+ <li class="md-nav__item">
1435
+ <a href="../../../models/circuits/provider.html" class="md-nav__link">
1436
+ Circuit Provider
1437
+ </a>
1438
+ </li>
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+ <li class="md-nav__item">
1449
+ <a href="../../../models/circuits/providernetwork.html" class="md-nav__link">
1450
+ Circuit Provider Network
1451
+ </a>
1452
+ </li>
1453
+
1454
+
1455
+
1456
+
1457
+ </ul>
1458
+ </nav>
1459
+ </li>
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+ <li class="md-nav__item md-nav__item--nested">
1471
+
1472
+
1473
+
1474
+
1475
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_2" >
1476
+
1477
+
1478
+
1479
+ <label class="md-nav__link" for="__nav_2_8_2" id="__nav_2_8_2_label" tabindex="0">
1480
+ DCIM
1481
+ <span class="md-nav__icon md-icon"></span>
1482
+ </label>
1483
+
1484
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_2_label" aria-expanded="false">
1485
+ <label class="md-nav__title" for="__nav_2_8_2">
1486
+ <span class="md-nav__icon md-icon"></span>
1487
+ DCIM
1488
+ </label>
1489
+ <ul class="md-nav__list" data-md-scrollfix>
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+ <li class="md-nav__item">
1497
+ <a href="../../../models/dcim/cable.html" class="md-nav__link">
1498
+ Cable
1499
+ </a>
1500
+ </li>
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+ <li class="md-nav__item">
1511
+ <a href="../../../models/dcim/consoleport.html" class="md-nav__link">
1512
+ Console Port
1513
+ </a>
1514
+ </li>
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+ <li class="md-nav__item">
1525
+ <a href="../../../models/dcim/consoleporttemplate.html" class="md-nav__link">
1526
+ Console Port Template
1527
+ </a>
1528
+ </li>
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+ <li class="md-nav__item">
1539
+ <a href="../../../models/dcim/consoleserverport.html" class="md-nav__link">
1540
+ Console Server Port
1541
+ </a>
1542
+ </li>
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+ <li class="md-nav__item">
1553
+ <a href="../../../models/dcim/consoleserverporttemplate.html" class="md-nav__link">
1554
+ Console Server Port Template
1555
+ </a>
1556
+ </li>
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+ <li class="md-nav__item">
1567
+ <a href="../../../models/dcim/device.html" class="md-nav__link">
1568
+ Device
1569
+ </a>
1570
+ </li>
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+ <li class="md-nav__item">
1581
+ <a href="../../../models/dcim/devicebay.html" class="md-nav__link">
1582
+ Device Bay
1583
+ </a>
1584
+ </li>
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+ <li class="md-nav__item">
1595
+ <a href="../../../models/dcim/devicebaytemplate.html" class="md-nav__link">
1596
+ Device Bay Template
1597
+ </a>
1598
+ </li>
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+ <li class="md-nav__item">
1609
+ <a href="../../../models/dcim/deviceredundancygroup.html" class="md-nav__link">
1610
+ Device Redundancy Group
1611
+ </a>
1612
+ </li>
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+ <li class="md-nav__item">
1623
+ <a href="../../../models/dcim/devicetype.html" class="md-nav__link">
1624
+ Device Type
1625
+ </a>
1626
+ </li>
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+ <li class="md-nav__item">
1637
+ <a href="../../../models/dcim/frontport.html" class="md-nav__link">
1638
+ Front Port
1639
+ </a>
1640
+ </li>
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+ <li class="md-nav__item">
1651
+ <a href="../../../models/dcim/frontporttemplate.html" class="md-nav__link">
1652
+ Front Port Template
1653
+ </a>
1654
+ </li>
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+ <li class="md-nav__item">
1665
+ <a href="../../../models/dcim/interface.html" class="md-nav__link">
1666
+ Interface
1667
+ </a>
1668
+ </li>
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+
1676
+
1677
+
1678
+ <li class="md-nav__item">
1679
+ <a href="../../../models/dcim/interfacetemplate.html" class="md-nav__link">
1680
+ Interface Template
1681
+ </a>
1682
+ </li>
1683
+
1684
+
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+ <li class="md-nav__item">
1693
+ <a href="../../../models/dcim/inventoryitem.html" class="md-nav__link">
1694
+ Inventory Item
1695
+ </a>
1696
+ </li>
1697
+
1698
+
1699
+
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+ <li class="md-nav__item">
1707
+ <a href="../../../models/dcim/location.html" class="md-nav__link">
1708
+ Location
1709
+ </a>
1710
+ </li>
1711
+
1712
+
1713
+
1714
+
1715
+
1716
+
1717
+
1718
+
1719
+
1720
+ <li class="md-nav__item">
1721
+ <a href="../../../models/dcim/locationtype.html" class="md-nav__link">
1722
+ Location Type
1723
+ </a>
1724
+ </li>
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+
1731
+
1732
+
1733
+
1734
+ <li class="md-nav__item">
1735
+ <a href="../../../models/dcim/manufacturer.html" class="md-nav__link">
1736
+ Manufacturer
1737
+ </a>
1738
+ </li>
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+ <li class="md-nav__item">
1749
+ <a href="../../../models/dcim/platform.html" class="md-nav__link">
1750
+ Platform
1751
+ </a>
1752
+ </li>
1753
+
1754
+
1755
+
1756
+
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+ <li class="md-nav__item">
1763
+ <a href="../../../models/dcim/powerfeed.html" class="md-nav__link">
1764
+ Power Feed
1765
+ </a>
1766
+ </li>
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+ <li class="md-nav__item">
1777
+ <a href="../../../models/dcim/poweroutlet.html" class="md-nav__link">
1778
+ Power Outlet
1779
+ </a>
1780
+ </li>
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+ <li class="md-nav__item">
1791
+ <a href="../../../models/dcim/poweroutlettemplate.html" class="md-nav__link">
1792
+ Power Outlet Template
1793
+ </a>
1794
+ </li>
1795
+
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+
1802
+
1803
+
1804
+ <li class="md-nav__item">
1805
+ <a href="../../../models/dcim/powerpanel.html" class="md-nav__link">
1806
+ Power Panel
1807
+ </a>
1808
+ </li>
1809
+
1810
+
1811
+
1812
+
1813
+
1814
+
1815
+
1816
+
1817
+
1818
+ <li class="md-nav__item">
1819
+ <a href="../../../models/dcim/powerport.html" class="md-nav__link">
1820
+ Power Port
1821
+ </a>
1822
+ </li>
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+ <li class="md-nav__item">
1833
+ <a href="../../../models/dcim/powerporttemplate.html" class="md-nav__link">
1834
+ Power Port Template
1835
+ </a>
1836
+ </li>
1837
+
1838
+
1839
+
1840
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+ <li class="md-nav__item">
1847
+ <a href="../../../models/dcim/rack.html" class="md-nav__link">
1848
+ Rack
1849
+ </a>
1850
+ </li>
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+ <li class="md-nav__item">
1861
+ <a href="../../../models/dcim/rackgroup.html" class="md-nav__link">
1862
+ Rack Group
1863
+ </a>
1864
+ </li>
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+ <li class="md-nav__item">
1875
+ <a href="../../../models/dcim/rackreservation.html" class="md-nav__link">
1876
+ Rack Reservation
1877
+ </a>
1878
+ </li>
1879
+
1880
+
1881
+
1882
+
1883
+
1884
+
1885
+
1886
+
1887
+
1888
+ <li class="md-nav__item">
1889
+ <a href="../../../models/dcim/rearport.html" class="md-nav__link">
1890
+ Rear Port
1891
+ </a>
1892
+ </li>
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1899
+
1900
+
1901
+
1902
+ <li class="md-nav__item">
1903
+ <a href="../../../models/dcim/rearporttemplate.html" class="md-nav__link">
1904
+ Rear Port Template
1905
+ </a>
1906
+ </li>
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+ <li class="md-nav__item">
1917
+ <a href="../../../models/dcim/virtualchassis.html" class="md-nav__link">
1918
+ Virtual Chassis
1919
+ </a>
1920
+ </li>
1921
+
1922
+
1923
+
1924
+
1925
+ </ul>
1926
+ </nav>
1927
+ </li>
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+
1937
+
1938
+ <li class="md-nav__item md-nav__item--nested">
1939
+
1940
+
1941
+
1942
+
1943
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_3" >
1944
+
1945
+
1946
+
1947
+ <label class="md-nav__link" for="__nav_2_8_3" id="__nav_2_8_3_label" tabindex="0">
1948
+ Extras
1949
+ <span class="md-nav__icon md-icon"></span>
1950
+ </label>
1951
+
1952
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_3_label" aria-expanded="false">
1953
+ <label class="md-nav__title" for="__nav_2_8_3">
1954
+ <span class="md-nav__icon md-icon"></span>
1955
+ Extras
1956
+ </label>
1957
+ <ul class="md-nav__list" data-md-scrollfix>
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+ <li class="md-nav__item">
1965
+ <a href="../../../models/extras/configcontext.html" class="md-nav__link">
1966
+ Config Context
1967
+ </a>
1968
+ </li>
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+ <li class="md-nav__item">
1979
+ <a href="../../../models/extras/configcontextschema.html" class="md-nav__link">
1980
+ Config Context Schema
1981
+ </a>
1982
+ </li>
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+
1992
+ <li class="md-nav__item">
1993
+ <a href="../../../models/extras/graphqlquery.html" class="md-nav__link">
1994
+ GraphQL Query
1995
+ </a>
1996
+ </li>
1997
+
1998
+
1999
+
2000
+
2001
+
2002
+
2003
+
2004
+
2005
+
2006
+ <li class="md-nav__item">
2007
+ <a href="../../../models/extras/imageattachment.html" class="md-nav__link">
2008
+ Image Attachment
2009
+ </a>
2010
+ </li>
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+ <li class="md-nav__item">
2021
+ <a href="../../../models/extras/job.html" class="md-nav__link">
2022
+ Job
2023
+ </a>
2024
+ </li>
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+ <li class="md-nav__item">
2035
+ <a href="../../../models/extras/joblogentry.html" class="md-nav__link">
2036
+ Job Log Entry
2037
+ </a>
2038
+ </li>
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+ <li class="md-nav__item">
2049
+ <a href="../../../models/extras/jobresult.html" class="md-nav__link">
2050
+ Job Result
2051
+ </a>
2052
+ </li>
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+
2061
+
2062
+ <li class="md-nav__item">
2063
+ <a href="../../../models/extras/role.html" class="md-nav__link">
2064
+ Role
2065
+ </a>
2066
+ </li>
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+ <li class="md-nav__item">
2077
+ <a href="../../../models/extras/secret.html" class="md-nav__link">
2078
+ Secret
2079
+ </a>
2080
+ </li>
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+ <li class="md-nav__item">
2091
+ <a href="../../../models/extras/secretsgroup.html" class="md-nav__link">
2092
+ Secrets group
2093
+ </a>
2094
+ </li>
2095
+
2096
+
2097
+
2098
+
2099
+ </ul>
2100
+ </nav>
2101
+ </li>
2102
+
2103
+
2104
+
2105
+
2106
+
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+ <li class="md-nav__item md-nav__item--nested">
2113
+
2114
+
2115
+
2116
+
2117
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_4" >
2118
+
2119
+
2120
+
2121
+ <label class="md-nav__link" for="__nav_2_8_4" id="__nav_2_8_4_label" tabindex="0">
2122
+ IPAM
2123
+ <span class="md-nav__icon md-icon"></span>
2124
+ </label>
2125
+
2126
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_4_label" aria-expanded="false">
2127
+ <label class="md-nav__title" for="__nav_2_8_4">
2128
+ <span class="md-nav__icon md-icon"></span>
2129
+ IPAM
2130
+ </label>
2131
+ <ul class="md-nav__list" data-md-scrollfix>
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+ <li class="md-nav__item">
2139
+ <a href="../../../models/ipam/ipaddress.html" class="md-nav__link">
2140
+ IP Address
2141
+ </a>
2142
+ </li>
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+ <li class="md-nav__item">
2153
+ <a href="../../../models/ipam/prefix.html" class="md-nav__link">
2154
+ Prefix
2155
+ </a>
2156
+ </li>
2157
+
2158
+
2159
+
2160
+
2161
+
2162
+
2163
+
2164
+
2165
+
2166
+ <li class="md-nav__item">
2167
+ <a href="../../../models/ipam/rir.html" class="md-nav__link">
2168
+ Rir
2169
+ </a>
2170
+ </li>
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+ <li class="md-nav__item">
2181
+ <a href="../../../models/ipam/routetarget.html" class="md-nav__link">
2182
+ Route Target
2183
+ </a>
2184
+ </li>
2185
+
2186
+
2187
+
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+ <li class="md-nav__item">
2195
+ <a href="../../../models/ipam/service.html" class="md-nav__link">
2196
+ Service
2197
+ </a>
2198
+ </li>
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+ <li class="md-nav__item">
2209
+ <a href="../../../models/ipam/vlan.html" class="md-nav__link">
2210
+ VLAN
2211
+ </a>
2212
+ </li>
2213
+
2214
+
2215
+
2216
+
2217
+
2218
+
2219
+
2220
+
2221
+
2222
+ <li class="md-nav__item">
2223
+ <a href="../../../models/ipam/vlangroup.html" class="md-nav__link">
2224
+ VLAN Group
2225
+ </a>
2226
+ </li>
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+
2234
+
2235
+
2236
+ <li class="md-nav__item">
2237
+ <a href="../../../models/ipam/vrf.html" class="md-nav__link">
2238
+ VRF
2239
+ </a>
2240
+ </li>
2241
+
2242
+
2243
+
2244
+
2245
+ </ul>
2246
+ </nav>
2247
+ </li>
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+ <li class="md-nav__item md-nav__item--nested">
2259
+
2260
+
2261
+
2262
+
2263
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_5" >
2264
+
2265
+
2266
+
2267
+ <label class="md-nav__link" for="__nav_2_8_5" id="__nav_2_8_5_label" tabindex="0">
2268
+ Tenancy
2269
+ <span class="md-nav__icon md-icon"></span>
2270
+ </label>
2271
+
2272
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_5_label" aria-expanded="false">
2273
+ <label class="md-nav__title" for="__nav_2_8_5">
2274
+ <span class="md-nav__icon md-icon"></span>
2275
+ Tenancy
2276
+ </label>
2277
+ <ul class="md-nav__list" data-md-scrollfix>
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+ <li class="md-nav__item">
2285
+ <a href="../../../models/tenancy/tenant.html" class="md-nav__link">
2286
+ Tenant
2287
+ </a>
2288
+ </li>
2289
+
2290
+
2291
+
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+ <li class="md-nav__item">
2299
+ <a href="../../../models/tenancy/tenantgroup.html" class="md-nav__link">
2300
+ Tenant Group
2301
+ </a>
2302
+ </li>
2303
+
2304
+
2305
+
2306
+
2307
+ </ul>
2308
+ </nav>
2309
+ </li>
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+ <li class="md-nav__item md-nav__item--nested">
2321
+
2322
+
2323
+
2324
+
2325
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_6" >
2326
+
2327
+
2328
+
2329
+ <label class="md-nav__link" for="__nav_2_8_6" id="__nav_2_8_6_label" tabindex="0">
2330
+ Users
2331
+ <span class="md-nav__icon md-icon"></span>
2332
+ </label>
2333
+
2334
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_6_label" aria-expanded="false">
2335
+ <label class="md-nav__title" for="__nav_2_8_6">
2336
+ <span class="md-nav__icon md-icon"></span>
2337
+ Users
2338
+ </label>
2339
+ <ul class="md-nav__list" data-md-scrollfix>
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+ <li class="md-nav__item">
2347
+ <a href="../../../models/users/objectpermission.html" class="md-nav__link">
2348
+ Object Permission
2349
+ </a>
2350
+ </li>
2351
+
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+ <li class="md-nav__item">
2361
+ <a href="../../../models/users/token.html" class="md-nav__link">
2362
+ Token
2363
+ </a>
2364
+ </li>
2365
+
2366
+
2367
+
2368
+
2369
+ </ul>
2370
+ </nav>
2371
+ </li>
2372
+
2373
+
2374
+
2375
+
2376
+
2377
+
2378
+
2379
+
2380
+
2381
+
2382
+ <li class="md-nav__item md-nav__item--nested">
2383
+
2384
+
2385
+
2386
+
2387
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_8_7" >
2388
+
2389
+
2390
+
2391
+ <label class="md-nav__link" for="__nav_2_8_7" id="__nav_2_8_7_label" tabindex="0">
2392
+ Virtualization
2393
+ <span class="md-nav__icon md-icon"></span>
2394
+ </label>
2395
+
2396
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_8_7_label" aria-expanded="false">
2397
+ <label class="md-nav__title" for="__nav_2_8_7">
2398
+ <span class="md-nav__icon md-icon"></span>
2399
+ Virtualization
2400
+ </label>
2401
+ <ul class="md-nav__list" data-md-scrollfix>
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+ <li class="md-nav__item">
2409
+ <a href="../../../models/virtualization/cluster.html" class="md-nav__link">
2410
+ Cluster
2411
+ </a>
2412
+ </li>
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+ <li class="md-nav__item">
2423
+ <a href="../../../models/virtualization/clustergroup.html" class="md-nav__link">
2424
+ Cluster Group
2425
+ </a>
2426
+ </li>
2427
+
2428
+
2429
+
2430
+
2431
+
2432
+
2433
+
2434
+
2435
+
2436
+ <li class="md-nav__item">
2437
+ <a href="../../../models/virtualization/clustertype.html" class="md-nav__link">
2438
+ Cluster Type
2439
+ </a>
2440
+ </li>
2441
+
2442
+
2443
+
2444
+
2445
+
2446
+
2447
+
2448
+
2449
+
2450
+ <li class="md-nav__item">
2451
+ <a href="../../../models/virtualization/virtualmachine.html" class="md-nav__link">
2452
+ Virtual Machine
2453
+ </a>
2454
+ </li>
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+
2461
+
2462
+
2463
+
2464
+ <li class="md-nav__item">
2465
+ <a href="../../../models/virtualization/vminterface.html" class="md-nav__link">
2466
+ VM Interface
2467
+ </a>
2468
+ </li>
2469
+
2470
+
2471
+
2472
+
2473
+ </ul>
2474
+ </nav>
2475
+ </li>
2476
+
2477
+
2478
+
2479
+
2480
+ </ul>
2481
+ </nav>
2482
+ </li>
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+ <li class="md-nav__item md-nav__item--nested">
2494
+
2495
+
2496
+
2497
+
2498
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_9" >
2499
+
2500
+
2501
+
2502
+ <label class="md-nav__link" for="__nav_2_9" id="__nav_2_9_label" tabindex="0">
1349
2503
  Additional Features
1350
2504
  <span class="md-nav__icon md-icon"></span>
1351
2505
  </label>
1352
2506
 
1353
- <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_8_label" aria-expanded="false">
1354
- <label class="md-nav__title" for="__nav_2_8">
2507
+ <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_9_label" aria-expanded="false">
2508
+ <label class="md-nav__title" for="__nav_2_9">
1355
2509
  <span class="md-nav__icon md-icon"></span>
1356
2510
  Additional Features
1357
2511
  </label>
@@ -1683,17 +2837,17 @@
1683
2837
 
1684
2838
 
1685
2839
 
1686
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_9" >
2840
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_10" >
1687
2841
 
1688
2842
 
1689
2843
 
1690
- <label class="md-nav__link" for="__nav_2_9" id="__nav_2_9_label" tabindex="0">
2844
+ <label class="md-nav__link" for="__nav_2_10" id="__nav_2_10_label" tabindex="0">
1691
2845
  REST API
1692
2846
  <span class="md-nav__icon md-icon"></span>
1693
2847
  </label>
1694
2848
 
1695
- <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_9_label" aria-expanded="false">
1696
- <label class="md-nav__title" for="__nav_2_9">
2849
+ <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_10_label" aria-expanded="false">
2850
+ <label class="md-nav__title" for="__nav_2_10">
1697
2851
  <span class="md-nav__icon md-icon"></span>
1698
2852
  REST API
1699
2853
  </label>
@@ -1741,6 +2895,20 @@
1741
2895
 
1742
2896
 
1743
2897
 
2898
+
2899
+
2900
+
2901
+
2902
+
2903
+ <li class="md-nav__item">
2904
+ <a href="../../../rest-api/ui-related-endpoints.html" class="md-nav__link">
2905
+ UI Endpoints
2906
+ </a>
2907
+ </li>
2908
+
2909
+
2910
+
2911
+
1744
2912
  </ul>
1745
2913
  </nav>
1746
2914
  </li>
@@ -1759,17 +2927,17 @@
1759
2927
 
1760
2928
 
1761
2929
 
1762
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_10" >
2930
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_11" >
1763
2931
 
1764
2932
 
1765
2933
 
1766
- <label class="md-nav__link" for="__nav_2_10" id="__nav_2_10_label" tabindex="0">
2934
+ <label class="md-nav__link" for="__nav_2_11" id="__nav_2_11_label" tabindex="0">
1767
2935
  GraphQL API
1768
2936
  <span class="md-nav__icon md-icon"></span>
1769
2937
  </label>
1770
2938
 
1771
- <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_10_label" aria-expanded="false">
1772
- <label class="md-nav__title" for="__nav_2_10">
2939
+ <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_11_label" aria-expanded="false">
2940
+ <label class="md-nav__title" for="__nav_2_11">
1773
2941
  <span class="md-nav__icon md-icon"></span>
1774
2942
  GraphQL API
1775
2943
  </label>
@@ -2949,7 +4117,11 @@ Relationships, etc.</p>
2949
4117
 
2950
4118
  <details class="quote">
2951
4119
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
2952
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
4120
+ <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>
4121
+ <span class="normal"><a href="#__codelineno-0-45"> 45</a></span>
4122
+ <span class="normal"><a href="#__codelineno-0-46"> 46</a></span>
4123
+ <span class="normal"><a href="#__codelineno-0-47"> 47</a></span>
4124
+ <span class="normal"><a href="#__codelineno-0-48"> 48</a></span>
2953
4125
  <span class="normal"><a href="#__codelineno-0-49"> 49</a></span>
2954
4126
  <span class="normal"><a href="#__codelineno-0-50"> 50</a></span>
2955
4127
  <span class="normal"><a href="#__codelineno-0-51"> 51</a></span>
@@ -3163,241 +4335,225 @@ Relationships, etc.</p>
3163
4335
  <span class="normal"><a href="#__codelineno-0-259">259</a></span>
3164
4336
  <span class="normal"><a href="#__codelineno-0-260">260</a></span>
3165
4337
  <span class="normal"><a href="#__codelineno-0-261">261</a></span>
3166
- <span class="normal"><a href="#__codelineno-0-262">262</a></span>
3167
- <span class="normal"><a href="#__codelineno-0-263">263</a></span>
3168
- <span class="normal"><a href="#__codelineno-0-264">264</a></span>
3169
- <span class="normal"><a href="#__codelineno-0-265">265</a></span>
3170
- <span class="normal"><a href="#__codelineno-0-266">266</a></span>
3171
- <span class="normal"><a href="#__codelineno-0-267">267</a></span>
3172
- <span class="normal"><a href="#__codelineno-0-268">268</a></span>
3173
- <span class="normal"><a href="#__codelineno-0-269">269</a></span>
3174
- <span class="normal"><a href="#__codelineno-0-270">270</a></span>
3175
- <span class="normal"><a href="#__codelineno-0-271">271</a></span>
3176
- <span class="normal"><a href="#__codelineno-0-272">272</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-48" name="__codelineno-0-48"></a><span class="k">class</span> <span class="nc">NautobotAppConfig</span><span class="p">(</span><span class="n">NautobotConfig</span><span class="p">):</span>
3177
- <a id="__codelineno-0-49" name="__codelineno-0-49"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
3178
- <a id="__codelineno-0-50" name="__codelineno-0-50"></a><span class="sd"> Subclass of Django&#39;s built-in AppConfig class, to be used for Nautobot plugins.</span>
3179
- <a id="__codelineno-0-51" name="__codelineno-0-51"></a><span class="sd"> &quot;&quot;&quot;</span>
3180
- <a id="__codelineno-0-52" name="__codelineno-0-52"></a>
3181
- <a id="__codelineno-0-53" name="__codelineno-0-53"></a> <span class="c1"># Plugin metadata</span>
3182
- <a id="__codelineno-0-54" name="__codelineno-0-54"></a> <span class="n">author</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3183
- <a id="__codelineno-0-55" name="__codelineno-0-55"></a> <span class="n">author_email</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3184
- <a id="__codelineno-0-56" name="__codelineno-0-56"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3185
- <a id="__codelineno-0-57" name="__codelineno-0-57"></a> <span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
3186
- <a id="__codelineno-0-58" name="__codelineno-0-58"></a>
3187
- <a id="__codelineno-0-59" name="__codelineno-0-59"></a> <span class="c1"># Root URL path under /plugins. If not set, the plugin&#39;s label will be used.</span>
3188
- <a id="__codelineno-0-60" name="__codelineno-0-60"></a> <span class="n">base_url</span> <span class="o">=</span> <span class="kc">None</span>
4338
+ <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>
4339
+ <a id="__codelineno-0-45" name="__codelineno-0-45"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
4340
+ <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>
4341
+ <a id="__codelineno-0-47" name="__codelineno-0-47"></a><span class="sd"> &quot;&quot;&quot;</span>
4342
+ <a id="__codelineno-0-48" name="__codelineno-0-48"></a>
4343
+ <a id="__codelineno-0-49" name="__codelineno-0-49"></a> <span class="c1"># Plugin metadata</span>
4344
+ <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>
4345
+ <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>
4346
+ <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>
4347
+ <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>
4348
+ <a id="__codelineno-0-54" name="__codelineno-0-54"></a>
4349
+ <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>
4350
+ <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>
4351
+ <a id="__codelineno-0-57" name="__codelineno-0-57"></a>
4352
+ <a id="__codelineno-0-58" name="__codelineno-0-58"></a> <span class="c1"># Minimum/maximum compatible versions of Nautobot</span>
4353
+ <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>
4354
+ <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>
3189
4355
  <a id="__codelineno-0-61" name="__codelineno-0-61"></a>
3190
- <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="c1"># Minimum/maximum compatible versions of Nautobot</span>
3191
- <a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">min_version</span> <span class="o">=</span> <span class="kc">None</span>
3192
- <a id="__codelineno-0-64" name="__codelineno-0-64"></a> <span class="n">max_version</span> <span class="o">=</span> <span class="kc">None</span>
3193
- <a id="__codelineno-0-65" name="__codelineno-0-65"></a>
3194
- <a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="c1"># Default configuration parameters</span>
3195
- <a id="__codelineno-0-67" name="__codelineno-0-67"></a> <span class="n">default_settings</span> <span class="o">=</span> <span class="p">{}</span>
3196
- <a id="__codelineno-0-68" name="__codelineno-0-68"></a>
3197
- <a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="c1"># Mandatory configuration parameters</span>
3198
- <a id="__codelineno-0-70" name="__codelineno-0-70"></a> <span class="n">required_settings</span> <span class="o">=</span> <span class="p">[]</span>
3199
- <a id="__codelineno-0-71" name="__codelineno-0-71"></a>
3200
- <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="c1"># Middleware classes provided by the plugin</span>
3201
- <a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">middleware</span> <span class="o">=</span> <span class="p">[]</span>
4356
+ <a id="__codelineno-0-62" name="__codelineno-0-62"></a> <span class="c1"># Default configuration parameters</span>
4357
+ <a id="__codelineno-0-63" name="__codelineno-0-63"></a> <span class="n">default_settings</span> <span class="o">=</span> <span class="p">{}</span>
4358
+ <a id="__codelineno-0-64" name="__codelineno-0-64"></a>
4359
+ <a id="__codelineno-0-65" name="__codelineno-0-65"></a> <span class="c1"># Mandatory configuration parameters</span>
4360
+ <a id="__codelineno-0-66" name="__codelineno-0-66"></a> <span class="n">required_settings</span> <span class="o">=</span> <span class="p">[]</span>
4361
+ <a id="__codelineno-0-67" name="__codelineno-0-67"></a>
4362
+ <a id="__codelineno-0-68" name="__codelineno-0-68"></a> <span class="c1"># Middleware classes provided by the plugin</span>
4363
+ <a id="__codelineno-0-69" name="__codelineno-0-69"></a> <span class="n">middleware</span> <span class="o">=</span> <span class="p">[]</span>
4364
+ <a id="__codelineno-0-70" name="__codelineno-0-70"></a>
4365
+ <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>
4366
+ <a id="__codelineno-0-72" name="__codelineno-0-72"></a> <span class="c1"># along with the plugin.</span>
4367
+ <a id="__codelineno-0-73" name="__codelineno-0-73"></a> <span class="n">installed_apps</span> <span class="o">=</span> <span class="p">[]</span>
3202
4368
  <a id="__codelineno-0-74" name="__codelineno-0-74"></a>
3203
- <a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="c1"># Extra installed apps provided or required by the plugin. These will be registered</span>
3204
- <a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="c1"># along with the plugin.</span>
3205
- <a id="__codelineno-0-77" name="__codelineno-0-77"></a> <span class="n">installed_apps</span> <span class="o">=</span> <span class="p">[]</span>
3206
- <a id="__codelineno-0-78" name="__codelineno-0-78"></a>
3207
- <a id="__codelineno-0-79" name="__codelineno-0-79"></a> <span class="c1"># Cacheops configuration. Cache all operations by default.</span>
3208
- <a id="__codelineno-0-80" name="__codelineno-0-80"></a> <span class="n">caching_config</span> <span class="o">=</span> <span class="p">{</span>
3209
- <a id="__codelineno-0-81" name="__codelineno-0-81"></a> <span class="s2">&quot;*&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;ops&quot;</span><span class="p">:</span> <span class="s2">&quot;all&quot;</span><span class="p">},</span>
3210
- <a id="__codelineno-0-82" name="__codelineno-0-82"></a> <span class="p">}</span>
3211
- <a id="__codelineno-0-83" name="__codelineno-0-83"></a>
3212
- <a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="c1"># Default constance configuration parameters</span>
3213
- <a id="__codelineno-0-85" name="__codelineno-0-85"></a> <span class="n">constance_config</span> <span class="o">=</span> <span class="p">{}</span>
3214
- <a id="__codelineno-0-86" name="__codelineno-0-86"></a>
3215
- <a id="__codelineno-0-87" name="__codelineno-0-87"></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>
3216
- <a id="__codelineno-0-88" name="__codelineno-0-88"></a> <span class="n">home_view_name</span> <span class="o">=</span> <span class="kc">None</span>
3217
- <a id="__codelineno-0-89" name="__codelineno-0-89"></a> <span class="n">config_view_name</span> <span class="o">=</span> <span class="kc">None</span>
3218
- <a id="__codelineno-0-90" name="__codelineno-0-90"></a> <span class="n">docs_view_name</span> <span class="o">=</span> <span class="kc">None</span>
3219
- <a id="__codelineno-0-91" name="__codelineno-0-91"></a>
3220
- <a id="__codelineno-0-92" name="__codelineno-0-92"></a> <span class="c1"># Default integration paths. Plugin authors can override these to customize the paths to</span>
3221
- <a id="__codelineno-0-93" name="__codelineno-0-93"></a> <span class="c1"># integrated components.</span>
3222
- <a id="__codelineno-0-94" name="__codelineno-0-94"></a> <span class="n">banner_function</span> <span class="o">=</span> <span class="s2">&quot;banner.banner&quot;</span>
3223
- <a id="__codelineno-0-95" name="__codelineno-0-95"></a> <span class="n">custom_validators</span> <span class="o">=</span> <span class="s2">&quot;custom_validators.custom_validators&quot;</span>
3224
- <a id="__codelineno-0-96" name="__codelineno-0-96"></a> <span class="n">datasource_contents</span> <span class="o">=</span> <span class="s2">&quot;datasources.datasource_contents&quot;</span>
3225
- <a id="__codelineno-0-97" name="__codelineno-0-97"></a> <span class="n">filter_extensions</span> <span class="o">=</span> <span class="s2">&quot;filter_extensions.filter_extensions&quot;</span>
3226
- <a id="__codelineno-0-98" name="__codelineno-0-98"></a> <span class="n">graphql_types</span> <span class="o">=</span> <span class="s2">&quot;graphql.types.graphql_types&quot;</span>
3227
- <a id="__codelineno-0-99" name="__codelineno-0-99"></a> <span class="n">homepage_layout</span> <span class="o">=</span> <span class="s2">&quot;homepage.layout&quot;</span>
3228
- <a id="__codelineno-0-100" name="__codelineno-0-100"></a> <span class="n">jinja_filters</span> <span class="o">=</span> <span class="s2">&quot;jinja_filters&quot;</span>
3229
- <a id="__codelineno-0-101" name="__codelineno-0-101"></a> <span class="n">jobs</span> <span class="o">=</span> <span class="s2">&quot;jobs.jobs&quot;</span>
3230
- <a id="__codelineno-0-102" name="__codelineno-0-102"></a> <span class="n">metrics</span> <span class="o">=</span> <span class="s2">&quot;metrics.metrics&quot;</span>
3231
- <a id="__codelineno-0-103" name="__codelineno-0-103"></a> <span class="n">menu_items</span> <span class="o">=</span> <span class="s2">&quot;navigation.menu_items&quot;</span>
3232
- <a id="__codelineno-0-104" name="__codelineno-0-104"></a> <span class="n">secrets_providers</span> <span class="o">=</span> <span class="s2">&quot;secrets.secrets_providers&quot;</span>
3233
- <a id="__codelineno-0-105" name="__codelineno-0-105"></a> <span class="n">template_extensions</span> <span class="o">=</span> <span class="s2">&quot;template_content.template_extensions&quot;</span>
3234
- <a id="__codelineno-0-106" name="__codelineno-0-106"></a> <span class="n">override_views</span> <span class="o">=</span> <span class="s2">&quot;views.override_views&quot;</span>
3235
- <a id="__codelineno-0-107" name="__codelineno-0-107"></a>
3236
- <a id="__codelineno-0-108" name="__codelineno-0-108"></a> <span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
3237
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
3238
- <a id="__codelineno-0-110" name="__codelineno-0-110"></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>
3239
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a>
3240
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
3241
- <a id="__codelineno-0-113" name="__codelineno-0-113"></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>
3242
- <a id="__codelineno-0-114" name="__codelineno-0-114"></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>
3243
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a>
3244
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
3245
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
3246
- <a id="__codelineno-0-118" name="__codelineno-0-118"></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>
3247
- <a id="__codelineno-0-119" name="__codelineno-0-119"></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>
3248
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="p">),</span>
3249
- <a id="__codelineno-0-121" name="__codelineno-0-121"></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>
3250
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
3251
- <a id="__codelineno-0-123" name="__codelineno-0-123"></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>
3252
- <a id="__codelineno-0-124" name="__codelineno-0-124"></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>
3253
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="p">),</span>
3254
- <a id="__codelineno-0-126" name="__codelineno-0-126"></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>
3255
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="p">}</span>
3256
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a>
3257
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="c1"># Register banner function (if defined)</span>
3258
- <a id="__codelineno-0-130" name="__codelineno-0-130"></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>
3259
- <a id="__codelineno-0-131" name="__codelineno-0-131"></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>
3260
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
3261
- <a id="__codelineno-0-133" name="__codelineno-0-133"></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>
3262
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a>
3263
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="c1"># Register model validators (if defined)</span>
3264
- <a id="__codelineno-0-136" name="__codelineno-0-136"></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>
3265
- <a id="__codelineno-0-137" name="__codelineno-0-137"></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>
3266
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
3267
- <a id="__codelineno-0-139" name="__codelineno-0-139"></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>
3268
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a>
3269
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="c1"># Register datasource contents (if defined)</span>
3270
- <a id="__codelineno-0-142" name="__codelineno-0-142"></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>
3271
- <a id="__codelineno-0-143" name="__codelineno-0-143"></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>
3272
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
3273
- <a id="__codelineno-0-145" name="__codelineno-0-145"></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>
3274
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a>
3275
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="c1"># Register GraphQL types (if defined)</span>
3276
- <a id="__codelineno-0-148" name="__codelineno-0-148"></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>
3277
- <a id="__codelineno-0-149" name="__codelineno-0-149"></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>
3278
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
3279
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a>
3280
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="c1"># Import jobs (if present)</span>
3281
- <a id="__codelineno-0-153" name="__codelineno-0-153"></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>
3282
- <a id="__codelineno-0-154" name="__codelineno-0-154"></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>
3283
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
3284
- <a id="__codelineno-0-156" name="__codelineno-0-156"></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>
4369
+ <a id="__codelineno-0-75" name="__codelineno-0-75"></a> <span class="c1"># Default constance configuration parameters</span>
4370
+ <a id="__codelineno-0-76" name="__codelineno-0-76"></a> <span class="n">constance_config</span> <span class="o">=</span> <span class="p">{}</span>
4371
+ <a id="__codelineno-0-77" name="__codelineno-0-77"></a>
4372
+ <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>
4373
+ <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>
4374
+ <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>
4375
+ <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>
4376
+ <a id="__codelineno-0-82" name="__codelineno-0-82"></a>
4377
+ <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>
4378
+ <a id="__codelineno-0-84" name="__codelineno-0-84"></a> <span class="c1"># integrated components.</span>
4379
+ <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>
4380
+ <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>
4381
+ <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>
4382
+ <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>
4383
+ <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>
4384
+ <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>
4385
+ <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>
4386
+ <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>
4387
+ <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>
4388
+ <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>
4389
+ <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>
4390
+ <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>
4391
+ <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>
4392
+ <a id="__codelineno-0-98" name="__codelineno-0-98"></a>
4393
+ <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>
4394
+ <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>
4395
+ <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>
4396
+ <a id="__codelineno-0-102" name="__codelineno-0-102"></a>
4397
+ <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>
4398
+ <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>
4399
+ <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>
4400
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a>
4401
+ <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>
4402
+ <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>
4403
+ <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>
4404
+ <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>
4405
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="p">),</span>
4406
+ <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>
4407
+ <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>
4408
+ <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>
4409
+ <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>
4410
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">),</span>
4411
+ <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>
4412
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="p">}</span>
4413
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a>
4414
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># Register banner function (if defined)</span>
4415
+ <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>
4416
+ <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>
4417
+ <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>
4418
+ <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>
4419
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a>
4420
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># Register model validators (if defined)</span>
4421
+ <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>
4422
+ <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>
4423
+ <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>
4424
+ <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>
4425
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a>
4426
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="c1"># Register datasource contents (if defined)</span>
4427
+ <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>
4428
+ <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>
4429
+ <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>
4430
+ <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>
4431
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a>
4432
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="c1"># Register GraphQL types (if defined)</span>
4433
+ <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>
4434
+ <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>
4435
+ <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>
4436
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a>
4437
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="c1"># Import jobs (if present)</span>
4438
+ <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>
4439
+ <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>
4440
+ <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>
4441
+ <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>
4442
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a>
4443
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Import metrics (if present)</span>
4444
+ <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>
4445
+ <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>
4446
+ <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>
4447
+ <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>
4448
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
4449
+ <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>
4450
+ <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>
3285
4451
  <a id="__codelineno-0-157" name="__codelineno-0-157"></a>
3286
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Import metrics (if present)</span>
3287
- <a id="__codelineno-0-159" name="__codelineno-0-159"></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>
3288
- <a id="__codelineno-0-160" name="__codelineno-0-160"></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>
3289
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
3290
- <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;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>
3291
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
3292
- <a id="__codelineno-0-164" name="__codelineno-0-164"></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>
3293
- <a id="__codelineno-0-165" name="__codelineno-0-165"></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>
3294
- <a id="__codelineno-0-166" name="__codelineno-0-166"></a>
3295
- <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
3296
- <a id="__codelineno-0-168" name="__codelineno-0-168"></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>
3297
- <a id="__codelineno-0-169" name="__codelineno-0-169"></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>
3298
- <a id="__codelineno-0-170" name="__codelineno-0-170"></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>
3299
- <a id="__codelineno-0-171" name="__codelineno-0-171"></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>
3300
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a>
3301
- <a id="__codelineno-0-173" name="__codelineno-0-173"></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>
3302
- <a id="__codelineno-0-174" name="__codelineno-0-174"></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>
3303
- <a id="__codelineno-0-175" name="__codelineno-0-175"></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>
3304
- <a id="__codelineno-0-176" name="__codelineno-0-176"></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>
3305
- <a id="__codelineno-0-177" name="__codelineno-0-177"></a>
3306
- <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="c1"># Register template content (if defined)</span>
3307
- <a id="__codelineno-0-179" name="__codelineno-0-179"></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>
3308
- <a id="__codelineno-0-180" name="__codelineno-0-180"></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>
3309
- <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
3310
- <a id="__codelineno-0-182" name="__codelineno-0-182"></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>
3311
- <a id="__codelineno-0-183" name="__codelineno-0-183"></a>
3312
- <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="c1"># Register custom jinja filters</span>
3313
- <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">try</span><span class="p">:</span>
3314
- <a id="__codelineno-0-186" name="__codelineno-0-186"></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>
3315
- <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;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
3316
- <a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
3317
- <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="k">pass</span>
3318
- <a id="__codelineno-0-190" name="__codelineno-0-190"></a>
3319
- <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="c1"># Register secrets providers (if any)</span>
3320
- <a id="__codelineno-0-192" name="__codelineno-0-192"></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>
3321
- <a id="__codelineno-0-193" name="__codelineno-0-193"></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>
3322
- <a id="__codelineno-0-194" name="__codelineno-0-194"></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>
3323
- <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
3324
- <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;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
3325
- <a id="__codelineno-0-197" name="__codelineno-0-197"></a>
3326
- <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="c1"># Register custom filters (if any)</span>
3327
- <a id="__codelineno-0-199" name="__codelineno-0-199"></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>
3328
- <a id="__codelineno-0-200" name="__codelineno-0-200"></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>
3329
- <a id="__codelineno-0-201" name="__codelineno-0-201"></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>
3330
- <a id="__codelineno-0-202" name="__codelineno-0-202"></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>
3331
- <a id="__codelineno-0-203" name="__codelineno-0-203"></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>
3332
- <a id="__codelineno-0-204" name="__codelineno-0-204"></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>
3333
- <a id="__codelineno-0-205" name="__codelineno-0-205"></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>
3334
- <a id="__codelineno-0-206" name="__codelineno-0-206"></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>
3335
- <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="p">)</span>
3336
- <a id="__codelineno-0-208" name="__codelineno-0-208"></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>
3337
- <a id="__codelineno-0-209" name="__codelineno-0-209"></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>
3338
- <a id="__codelineno-0-210" name="__codelineno-0-210"></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>
3339
- <a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="p">)</span>
4452
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
4453
+ <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>
4454
+ <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>
4455
+ <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>
4456
+ <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>
4457
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a>
4458
+ <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>
4459
+ <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>
4460
+ <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>
4461
+ <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>
4462
+ <a id="__codelineno-0-168" name="__codelineno-0-168"></a>
4463
+ <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="c1"># Register template content (if defined)</span>
4464
+ <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>
4465
+ <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>
4466
+ <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>
4467
+ <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>
4468
+ <a id="__codelineno-0-174" name="__codelineno-0-174"></a>
4469
+ <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="c1"># Register custom jinja filters</span>
4470
+ <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="k">try</span><span class="p">:</span>
4471
+ <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>
4472
+ <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>
4473
+ <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
4474
+ <a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">pass</span>
4475
+ <a id="__codelineno-0-181" name="__codelineno-0-181"></a>
4476
+ <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="c1"># Register secrets providers (if any)</span>
4477
+ <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>
4478
+ <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>
4479
+ <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>
4480
+ <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>
4481
+ <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>
4482
+ <a id="__codelineno-0-188" name="__codelineno-0-188"></a>
4483
+ <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="c1"># Register custom filters (if any)</span>
4484
+ <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>
4485
+ <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>
4486
+ <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>
4487
+ <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>
4488
+ <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>
4489
+ <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>
4490
+ <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>
4491
+ <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>
4492
+ <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="p">)</span>
4493
+ <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>
4494
+ <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>
4495
+ <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>
4496
+ <a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="p">)</span>
4497
+ <a id="__codelineno-0-203" name="__codelineno-0-203"></a>
4498
+ <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="c1"># Register override view (if any)</span>
4499
+ <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>
4500
+ <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>
4501
+ <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>
4502
+ <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>
4503
+ <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>
4504
+ <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="p">)</span>
4505
+ <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>
3340
4506
  <a id="__codelineno-0-212" name="__codelineno-0-212"></a>
3341
- <a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="c1"># Register override view (if any)</span>
3342
- <a id="__codelineno-0-214" name="__codelineno-0-214"></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>
3343
- <a id="__codelineno-0-215" name="__codelineno-0-215"></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>
3344
- <a id="__codelineno-0-216" name="__codelineno-0-216"></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>
3345
- <a id="__codelineno-0-217" name="__codelineno-0-217"></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>
3346
- <a id="__codelineno-0-218" name="__codelineno-0-218"></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>
3347
- <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="p">)</span>
3348
- <a id="__codelineno-0-220" name="__codelineno-0-220"></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>
3349
- <a id="__codelineno-0-221" name="__codelineno-0-221"></a>
3350
- <a id="__codelineno-0-222" name="__codelineno-0-222"></a> <span class="nd">@classmethod</span>
3351
- <a id="__codelineno-0-223" name="__codelineno-0-223"></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>
3352
- <a id="__codelineno-0-224" name="__codelineno-0-224"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
3353
- <a id="__codelineno-0-225" name="__codelineno-0-225"></a>
3354
- <a id="__codelineno-0-226" name="__codelineno-0-226"></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>
3355
- <a id="__codelineno-0-227" name="__codelineno-0-227"></a>
3356
- <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="c1"># Enforce version constraints</span>
3357
- <a id="__codelineno-0-229" name="__codelineno-0-229"></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>
3358
- <a id="__codelineno-0-230" name="__codelineno-0-230"></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>
3359
- <a id="__codelineno-0-231" name="__codelineno-0-231"></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>
3360
- <a id="__codelineno-0-232" name="__codelineno-0-232"></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>
3361
- <a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3362
- <a id="__codelineno-0-234" name="__codelineno-0-234"></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>
3363
- <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="p">)</span>
3364
- <a id="__codelineno-0-236" name="__codelineno-0-236"></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>
3365
- <a id="__codelineno-0-237" name="__codelineno-0-237"></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>
3366
- <a id="__codelineno-0-238" name="__codelineno-0-238"></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>
3367
- <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3368
- <a id="__codelineno-0-240" name="__codelineno-0-240"></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>
3369
- <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="p">)</span>
3370
- <a id="__codelineno-0-242" name="__codelineno-0-242"></a>
3371
- <a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
3372
- <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
3373
- <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
3374
- <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
3375
- <a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="s2">&quot;caching_config&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
3376
- <a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
3377
- <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3378
- <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3379
- <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3380
- <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="p">}</span>
3381
- <a id="__codelineno-0-253" name="__codelineno-0-253"></a>
3382
- <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="c1"># Validate user settings</span>
3383
- <a id="__codelineno-0-255" name="__codelineno-0-255"></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>
3384
- <a id="__codelineno-0-256" name="__codelineno-0-256"></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>
3385
- <a id="__codelineno-0-257" name="__codelineno-0-257"></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>
3386
- <a id="__codelineno-0-258" name="__codelineno-0-258"></a>
3387
- <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># Validate the required_settings</span>
3388
- <a id="__codelineno-0-260" name="__codelineno-0-260"></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>
3389
- <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="p">:</span>
3390
- <a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3391
- <a id="__codelineno-0-263" name="__codelineno-0-263"></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>
3392
- <a id="__codelineno-0-264" name="__codelineno-0-264"></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>
3393
- <a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="p">)</span>
3394
- <a id="__codelineno-0-266" name="__codelineno-0-266"></a>
3395
- <a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="c1"># Apply default configuration values</span>
3396
- <a id="__codelineno-0-268" name="__codelineno-0-268"></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>
3397
- <a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="c1"># user_config and constance_config take precedence</span>
3398
- <a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
3399
- <a id="__codelineno-0-271" name="__codelineno-0-271"></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>
3400
- <a id="__codelineno-0-272" name="__codelineno-0-272"></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>
4507
+ <a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="nd">@classmethod</span>
4508
+ <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>
4509
+ <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>
4510
+ <a id="__codelineno-0-216" name="__codelineno-0-216"></a>
4511
+ <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>
4512
+ <a id="__codelineno-0-218" name="__codelineno-0-218"></a>
4513
+ <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="c1"># Enforce version constraints</span>
4514
+ <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>
4515
+ <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>
4516
+ <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>
4517
+ <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>
4518
+ <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4519
+ <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>
4520
+ <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="p">)</span>
4521
+ <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>
4522
+ <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>
4523
+ <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>
4524
+ <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4525
+ <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>
4526
+ <a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="p">)</span>
4527
+ <a id="__codelineno-0-233" name="__codelineno-0-233"></a>
4528
+ <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>
4529
+ <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>
4530
+ <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>
4531
+ <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
4532
+ <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>
4533
+ <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>
4534
+ <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>
4535
+ <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>
4536
+ <a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="p">}</span>
4537
+ <a id="__codelineno-0-243" name="__codelineno-0-243"></a>
4538
+ <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># Validate user settings</span>
4539
+ <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>
4540
+ <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>
4541
+ <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>
4542
+ <a id="__codelineno-0-248" name="__codelineno-0-248"></a>
4543
+ <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="c1"># Validate the required_settings</span>
4544
+ <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>
4545
+ <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>
4546
+ <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4547
+ <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>
4548
+ <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>
4549
+ <a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="p">)</span>
4550
+ <a id="__codelineno-0-256" name="__codelineno-0-256"></a>
4551
+ <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="c1"># Apply default configuration values</span>
4552
+ <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>
4553
+ <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># user_config and constance_config take precedence</span>
4554
+ <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>
4555
+ <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>
4556
+ <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>
3401
4557
  </code></pre></div></td></tr></table></div>
3402
4558
  </details>
3403
4559
 
@@ -3429,7 +4585,16 @@ Relationships, etc.</p>
3429
4585
 
3430
4586
  <details class="quote">
3431
4587
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
3432
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-108">108</a></span>
4588
+ <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>
4589
+ <span class="normal"><a href="#__codelineno-0-100">100</a></span>
4590
+ <span class="normal"><a href="#__codelineno-0-101">101</a></span>
4591
+ <span class="normal"><a href="#__codelineno-0-102">102</a></span>
4592
+ <span class="normal"><a href="#__codelineno-0-103">103</a></span>
4593
+ <span class="normal"><a href="#__codelineno-0-104">104</a></span>
4594
+ <span class="normal"><a href="#__codelineno-0-105">105</a></span>
4595
+ <span class="normal"><a href="#__codelineno-0-106">106</a></span>
4596
+ <span class="normal"><a href="#__codelineno-0-107">107</a></span>
4597
+ <span class="normal"><a href="#__codelineno-0-108">108</a></span>
3433
4598
  <span class="normal"><a href="#__codelineno-0-109">109</a></span>
3434
4599
  <span class="normal"><a href="#__codelineno-0-110">110</a></span>
3435
4600
  <span class="normal"><a href="#__codelineno-0-111">111</a></span>
@@ -3532,128 +4697,119 @@ Relationships, etc.</p>
3532
4697
  <span class="normal"><a href="#__codelineno-0-208">208</a></span>
3533
4698
  <span class="normal"><a href="#__codelineno-0-209">209</a></span>
3534
4699
  <span class="normal"><a href="#__codelineno-0-210">210</a></span>
3535
- <span class="normal"><a href="#__codelineno-0-211">211</a></span>
3536
- <span class="normal"><a href="#__codelineno-0-212">212</a></span>
3537
- <span class="normal"><a href="#__codelineno-0-213">213</a></span>
3538
- <span class="normal"><a href="#__codelineno-0-214">214</a></span>
3539
- <span class="normal"><a href="#__codelineno-0-215">215</a></span>
3540
- <span class="normal"><a href="#__codelineno-0-216">216</a></span>
3541
- <span class="normal"><a href="#__codelineno-0-217">217</a></span>
3542
- <span class="normal"><a href="#__codelineno-0-218">218</a></span>
3543
- <span class="normal"><a href="#__codelineno-0-219">219</a></span>
3544
- <span class="normal"><a href="#__codelineno-0-220">220</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-108" name="__codelineno-0-108"></a><span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
3545
- <a id="__codelineno-0-109" name="__codelineno-0-109"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Callback after plugin app is loaded.&quot;&quot;&quot;</span>
3546
- <a id="__codelineno-0-110" name="__codelineno-0-110"></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>
3547
- <a id="__codelineno-0-111" name="__codelineno-0-111"></a>
3548
- <a id="__codelineno-0-112" name="__codelineno-0-112"></a> <span class="c1"># Introspect URL patterns and models to make available to the installed-plugins detail UI view.</span>
3549
- <a id="__codelineno-0-113" name="__codelineno-0-113"></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>
3550
- <a id="__codelineno-0-114" name="__codelineno-0-114"></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>
3551
- <a id="__codelineno-0-115" name="__codelineno-0-115"></a>
3552
- <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="bp">self</span><span class="o">.</span><span class="n">features</span> <span class="o">=</span> <span class="p">{</span>
3553
- <a id="__codelineno-0-117" name="__codelineno-0-117"></a> <span class="s2">&quot;api_urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
3554
- <a id="__codelineno-0-118" name="__codelineno-0-118"></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>
3555
- <a id="__codelineno-0-119" name="__codelineno-0-119"></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>
3556
- <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="p">),</span>
3557
- <a id="__codelineno-0-121" name="__codelineno-0-121"></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>
3558
- <a id="__codelineno-0-122" name="__codelineno-0-122"></a> <span class="s2">&quot;urlpatterns&quot;</span><span class="p">:</span> <span class="nb">sorted</span><span class="p">(</span>
3559
- <a id="__codelineno-0-123" name="__codelineno-0-123"></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>
3560
- <a id="__codelineno-0-124" name="__codelineno-0-124"></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>
3561
- <a id="__codelineno-0-125" name="__codelineno-0-125"></a> <span class="p">),</span>
3562
- <a id="__codelineno-0-126" name="__codelineno-0-126"></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>
3563
- <a id="__codelineno-0-127" name="__codelineno-0-127"></a> <span class="p">}</span>
3564
- <a id="__codelineno-0-128" name="__codelineno-0-128"></a>
3565
- <a id="__codelineno-0-129" name="__codelineno-0-129"></a> <span class="c1"># Register banner function (if defined)</span>
3566
- <a id="__codelineno-0-130" name="__codelineno-0-130"></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>
3567
- <a id="__codelineno-0-131" name="__codelineno-0-131"></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>
3568
- <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="n">register_banner_function</span><span class="p">(</span><span class="n">banner_function</span><span class="p">)</span>
3569
- <a id="__codelineno-0-133" name="__codelineno-0-133"></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>
3570
- <a id="__codelineno-0-134" name="__codelineno-0-134"></a>
3571
- <a id="__codelineno-0-135" name="__codelineno-0-135"></a> <span class="c1"># Register model validators (if defined)</span>
3572
- <a id="__codelineno-0-136" name="__codelineno-0-136"></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>
3573
- <a id="__codelineno-0-137" name="__codelineno-0-137"></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>
3574
- <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="n">register_custom_validators</span><span class="p">(</span><span class="n">validators</span><span class="p">)</span>
3575
- <a id="__codelineno-0-139" name="__codelineno-0-139"></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>
3576
- <a id="__codelineno-0-140" name="__codelineno-0-140"></a>
3577
- <a id="__codelineno-0-141" name="__codelineno-0-141"></a> <span class="c1"># Register datasource contents (if defined)</span>
3578
- <a id="__codelineno-0-142" name="__codelineno-0-142"></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>
3579
- <a id="__codelineno-0-143" name="__codelineno-0-143"></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>
3580
- <a id="__codelineno-0-144" name="__codelineno-0-144"></a> <span class="n">register_datasource_contents</span><span class="p">(</span><span class="n">datasource_contents</span><span class="p">)</span>
3581
- <a id="__codelineno-0-145" name="__codelineno-0-145"></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>
3582
- <a id="__codelineno-0-146" name="__codelineno-0-146"></a>
3583
- <a id="__codelineno-0-147" name="__codelineno-0-147"></a> <span class="c1"># Register GraphQL types (if defined)</span>
3584
- <a id="__codelineno-0-148" name="__codelineno-0-148"></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>
3585
- <a id="__codelineno-0-149" name="__codelineno-0-149"></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>
3586
- <a id="__codelineno-0-150" name="__codelineno-0-150"></a> <span class="n">register_graphql_types</span><span class="p">(</span><span class="n">graphql_types</span><span class="p">)</span>
3587
- <a id="__codelineno-0-151" name="__codelineno-0-151"></a>
3588
- <a id="__codelineno-0-152" name="__codelineno-0-152"></a> <span class="c1"># Import jobs (if present)</span>
3589
- <a id="__codelineno-0-153" name="__codelineno-0-153"></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>
3590
- <a id="__codelineno-0-154" name="__codelineno-0-154"></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>
3591
- <a id="__codelineno-0-155" name="__codelineno-0-155"></a> <span class="n">register_jobs</span><span class="p">(</span><span class="n">jobs</span><span class="p">)</span>
3592
- <a id="__codelineno-0-156" name="__codelineno-0-156"></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>
4700
+ <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>
4701
+ <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>
4702
+ <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>
4703
+ <a id="__codelineno-0-102" name="__codelineno-0-102"></a>
4704
+ <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>
4705
+ <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>
4706
+ <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>
4707
+ <a id="__codelineno-0-106" name="__codelineno-0-106"></a>
4708
+ <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>
4709
+ <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>
4710
+ <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>
4711
+ <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>
4712
+ <a id="__codelineno-0-111" name="__codelineno-0-111"></a> <span class="p">),</span>
4713
+ <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>
4714
+ <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>
4715
+ <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>
4716
+ <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>
4717
+ <a id="__codelineno-0-116" name="__codelineno-0-116"></a> <span class="p">),</span>
4718
+ <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>
4719
+ <a id="__codelineno-0-118" name="__codelineno-0-118"></a> <span class="p">}</span>
4720
+ <a id="__codelineno-0-119" name="__codelineno-0-119"></a>
4721
+ <a id="__codelineno-0-120" name="__codelineno-0-120"></a> <span class="c1"># Register banner function (if defined)</span>
4722
+ <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>
4723
+ <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>
4724
+ <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>
4725
+ <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>
4726
+ <a id="__codelineno-0-125" name="__codelineno-0-125"></a>
4727
+ <a id="__codelineno-0-126" name="__codelineno-0-126"></a> <span class="c1"># Register model validators (if defined)</span>
4728
+ <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>
4729
+ <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>
4730
+ <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>
4731
+ <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>
4732
+ <a id="__codelineno-0-131" name="__codelineno-0-131"></a>
4733
+ <a id="__codelineno-0-132" name="__codelineno-0-132"></a> <span class="c1"># Register datasource contents (if defined)</span>
4734
+ <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>
4735
+ <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>
4736
+ <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>
4737
+ <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>
4738
+ <a id="__codelineno-0-137" name="__codelineno-0-137"></a>
4739
+ <a id="__codelineno-0-138" name="__codelineno-0-138"></a> <span class="c1"># Register GraphQL types (if defined)</span>
4740
+ <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>
4741
+ <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>
4742
+ <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>
4743
+ <a id="__codelineno-0-142" name="__codelineno-0-142"></a>
4744
+ <a id="__codelineno-0-143" name="__codelineno-0-143"></a> <span class="c1"># Import jobs (if present)</span>
4745
+ <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>
4746
+ <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>
4747
+ <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>
4748
+ <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>
4749
+ <a id="__codelineno-0-148" name="__codelineno-0-148"></a>
4750
+ <a id="__codelineno-0-149" name="__codelineno-0-149"></a> <span class="c1"># Import metrics (if present)</span>
4751
+ <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>
4752
+ <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>
4753
+ <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>
4754
+ <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>
4755
+ <a id="__codelineno-0-154" name="__codelineno-0-154"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
4756
+ <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>
4757
+ <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>
3593
4758
  <a id="__codelineno-0-157" name="__codelineno-0-157"></a>
3594
- <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Import metrics (if present)</span>
3595
- <a id="__codelineno-0-159" name="__codelineno-0-159"></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>
3596
- <a id="__codelineno-0-160" name="__codelineno-0-160"></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>
3597
- <a id="__codelineno-0-161" name="__codelineno-0-161"></a> <span class="n">register_metrics</span><span class="p">(</span><span class="n">metrics</span><span class="p">)</span>
3598
- <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;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>
3599
- <a id="__codelineno-0-163" name="__codelineno-0-163"></a> <span class="c1"># Inject the metrics to discover into the signal handler.</span>
3600
- <a id="__codelineno-0-164" name="__codelineno-0-164"></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>
3601
- <a id="__codelineno-0-165" name="__codelineno-0-165"></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>
3602
- <a id="__codelineno-0-166" name="__codelineno-0-166"></a>
3603
- <a id="__codelineno-0-167" name="__codelineno-0-167"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
3604
- <a id="__codelineno-0-168" name="__codelineno-0-168"></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>
3605
- <a id="__codelineno-0-169" name="__codelineno-0-169"></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>
3606
- <a id="__codelineno-0-170" name="__codelineno-0-170"></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>
3607
- <a id="__codelineno-0-171" name="__codelineno-0-171"></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>
3608
- <a id="__codelineno-0-172" name="__codelineno-0-172"></a>
3609
- <a id="__codelineno-0-173" name="__codelineno-0-173"></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>
3610
- <a id="__codelineno-0-174" name="__codelineno-0-174"></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>
3611
- <a id="__codelineno-0-175" name="__codelineno-0-175"></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>
3612
- <a id="__codelineno-0-176" name="__codelineno-0-176"></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>
3613
- <a id="__codelineno-0-177" name="__codelineno-0-177"></a>
3614
- <a id="__codelineno-0-178" name="__codelineno-0-178"></a> <span class="c1"># Register template content (if defined)</span>
3615
- <a id="__codelineno-0-179" name="__codelineno-0-179"></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>
3616
- <a id="__codelineno-0-180" name="__codelineno-0-180"></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>
3617
- <a id="__codelineno-0-181" name="__codelineno-0-181"></a> <span class="n">register_template_extensions</span><span class="p">(</span><span class="n">template_extensions</span><span class="p">)</span>
3618
- <a id="__codelineno-0-182" name="__codelineno-0-182"></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>
3619
- <a id="__codelineno-0-183" name="__codelineno-0-183"></a>
3620
- <a id="__codelineno-0-184" name="__codelineno-0-184"></a> <span class="c1"># Register custom jinja filters</span>
3621
- <a id="__codelineno-0-185" name="__codelineno-0-185"></a> <span class="k">try</span><span class="p">:</span>
3622
- <a id="__codelineno-0-186" name="__codelineno-0-186"></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>
3623
- <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;jinja_filters&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
3624
- <a id="__codelineno-0-188" name="__codelineno-0-188"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
3625
- <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="k">pass</span>
3626
- <a id="__codelineno-0-190" name="__codelineno-0-190"></a>
3627
- <a id="__codelineno-0-191" name="__codelineno-0-191"></a> <span class="c1"># Register secrets providers (if any)</span>
3628
- <a id="__codelineno-0-192" name="__codelineno-0-192"></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>
3629
- <a id="__codelineno-0-193" name="__codelineno-0-193"></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>
3630
- <a id="__codelineno-0-194" name="__codelineno-0-194"></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>
3631
- <a id="__codelineno-0-195" name="__codelineno-0-195"></a> <span class="n">register_secrets_provider</span><span class="p">(</span><span class="n">secrets_provider</span><span class="p">)</span>
3632
- <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;secrets_providers&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">secrets_providers</span>
3633
- <a id="__codelineno-0-197" name="__codelineno-0-197"></a>
3634
- <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="c1"># Register custom filters (if any)</span>
3635
- <a id="__codelineno-0-199" name="__codelineno-0-199"></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>
3636
- <a id="__codelineno-0-200" name="__codelineno-0-200"></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>
3637
- <a id="__codelineno-0-201" name="__codelineno-0-201"></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>
3638
- <a id="__codelineno-0-202" name="__codelineno-0-202"></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>
3639
- <a id="__codelineno-0-203" name="__codelineno-0-203"></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>
3640
- <a id="__codelineno-0-204" name="__codelineno-0-204"></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>
3641
- <a id="__codelineno-0-205" name="__codelineno-0-205"></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>
3642
- <a id="__codelineno-0-206" name="__codelineno-0-206"></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>
3643
- <a id="__codelineno-0-207" name="__codelineno-0-207"></a> <span class="p">)</span>
3644
- <a id="__codelineno-0-208" name="__codelineno-0-208"></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>
3645
- <a id="__codelineno-0-209" name="__codelineno-0-209"></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>
3646
- <a id="__codelineno-0-210" name="__codelineno-0-210"></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>
3647
- <a id="__codelineno-0-211" name="__codelineno-0-211"></a> <span class="p">)</span>
3648
- <a id="__codelineno-0-212" name="__codelineno-0-212"></a>
3649
- <a id="__codelineno-0-213" name="__codelineno-0-213"></a> <span class="c1"># Register override view (if any)</span>
3650
- <a id="__codelineno-0-214" name="__codelineno-0-214"></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>
3651
- <a id="__codelineno-0-215" name="__codelineno-0-215"></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>
3652
- <a id="__codelineno-0-216" name="__codelineno-0-216"></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>
3653
- <a id="__codelineno-0-217" name="__codelineno-0-217"></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>
3654
- <a id="__codelineno-0-218" name="__codelineno-0-218"></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>
3655
- <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="p">)</span>
3656
- <a id="__codelineno-0-220" name="__codelineno-0-220"></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>
4759
+ <a id="__codelineno-0-158" name="__codelineno-0-158"></a> <span class="c1"># Register plugin navigation menu items (if defined)</span>
4760
+ <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>
4761
+ <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>
4762
+ <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>
4763
+ <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>
4764
+ <a id="__codelineno-0-163" name="__codelineno-0-163"></a>
4765
+ <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>
4766
+ <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>
4767
+ <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>
4768
+ <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>
4769
+ <a id="__codelineno-0-168" name="__codelineno-0-168"></a>
4770
+ <a id="__codelineno-0-169" name="__codelineno-0-169"></a> <span class="c1"># Register template content (if defined)</span>
4771
+ <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>
4772
+ <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>
4773
+ <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>
4774
+ <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>
4775
+ <a id="__codelineno-0-174" name="__codelineno-0-174"></a>
4776
+ <a id="__codelineno-0-175" name="__codelineno-0-175"></a> <span class="c1"># Register custom jinja filters</span>
4777
+ <a id="__codelineno-0-176" name="__codelineno-0-176"></a> <span class="k">try</span><span class="p">:</span>
4778
+ <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>
4779
+ <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>
4780
+ <a id="__codelineno-0-179" name="__codelineno-0-179"></a> <span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
4781
+ <a id="__codelineno-0-180" name="__codelineno-0-180"></a> <span class="k">pass</span>
4782
+ <a id="__codelineno-0-181" name="__codelineno-0-181"></a>
4783
+ <a id="__codelineno-0-182" name="__codelineno-0-182"></a> <span class="c1"># Register secrets providers (if any)</span>
4784
+ <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>
4785
+ <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>
4786
+ <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>
4787
+ <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>
4788
+ <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>
4789
+ <a id="__codelineno-0-188" name="__codelineno-0-188"></a>
4790
+ <a id="__codelineno-0-189" name="__codelineno-0-189"></a> <span class="c1"># Register custom filters (if any)</span>
4791
+ <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>
4792
+ <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>
4793
+ <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>
4794
+ <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>
4795
+ <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>
4796
+ <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>
4797
+ <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>
4798
+ <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>
4799
+ <a id="__codelineno-0-198" name="__codelineno-0-198"></a> <span class="p">)</span>
4800
+ <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>
4801
+ <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>
4802
+ <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>
4803
+ <a id="__codelineno-0-202" name="__codelineno-0-202"></a> <span class="p">)</span>
4804
+ <a id="__codelineno-0-203" name="__codelineno-0-203"></a>
4805
+ <a id="__codelineno-0-204" name="__codelineno-0-204"></a> <span class="c1"># Register override view (if any)</span>
4806
+ <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>
4807
+ <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>
4808
+ <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>
4809
+ <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>
4810
+ <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>
4811
+ <a id="__codelineno-0-210" name="__codelineno-0-210"></a> <span class="p">)</span>
4812
+ <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>
3657
4813
  </code></pre></div></td></tr></table></div>
3658
4814
  </details>
3659
4815
  </div>
@@ -3680,7 +4836,16 @@ Relationships, etc.</p>
3680
4836
 
3681
4837
  <details class="quote">
3682
4838
  <summary>Source code in <code>nautobot/extras/plugins/__init__.py</code></summary>
3683
- <div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-222">222</a></span>
4839
+ <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>
4840
+ <span class="normal"><a href="#__codelineno-0-214">214</a></span>
4841
+ <span class="normal"><a href="#__codelineno-0-215">215</a></span>
4842
+ <span class="normal"><a href="#__codelineno-0-216">216</a></span>
4843
+ <span class="normal"><a href="#__codelineno-0-217">217</a></span>
4844
+ <span class="normal"><a href="#__codelineno-0-218">218</a></span>
4845
+ <span class="normal"><a href="#__codelineno-0-219">219</a></span>
4846
+ <span class="normal"><a href="#__codelineno-0-220">220</a></span>
4847
+ <span class="normal"><a href="#__codelineno-0-221">221</a></span>
4848
+ <span class="normal"><a href="#__codelineno-0-222">222</a></span>
3684
4849
  <span class="normal"><a href="#__codelineno-0-223">223</a></span>
3685
4850
  <span class="normal"><a href="#__codelineno-0-224">224</a></span>
3686
4851
  <span class="normal"><a href="#__codelineno-0-225">225</a></span>
@@ -3720,67 +4885,56 @@ Relationships, etc.</p>
3720
4885
  <span class="normal"><a href="#__codelineno-0-259">259</a></span>
3721
4886
  <span class="normal"><a href="#__codelineno-0-260">260</a></span>
3722
4887
  <span class="normal"><a href="#__codelineno-0-261">261</a></span>
3723
- <span class="normal"><a href="#__codelineno-0-262">262</a></span>
3724
- <span class="normal"><a href="#__codelineno-0-263">263</a></span>
3725
- <span class="normal"><a href="#__codelineno-0-264">264</a></span>
3726
- <span class="normal"><a href="#__codelineno-0-265">265</a></span>
3727
- <span class="normal"><a href="#__codelineno-0-266">266</a></span>
3728
- <span class="normal"><a href="#__codelineno-0-267">267</a></span>
3729
- <span class="normal"><a href="#__codelineno-0-268">268</a></span>
3730
- <span class="normal"><a href="#__codelineno-0-269">269</a></span>
3731
- <span class="normal"><a href="#__codelineno-0-270">270</a></span>
3732
- <span class="normal"><a href="#__codelineno-0-271">271</a></span>
3733
- <span class="normal"><a href="#__codelineno-0-272">272</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-222" name="__codelineno-0-222"></a><span class="nd">@classmethod</span>
3734
- <a id="__codelineno-0-223" name="__codelineno-0-223"></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>
3735
- <a id="__codelineno-0-224" name="__codelineno-0-224"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;Validate the user_config for baseline correctness.&quot;&quot;&quot;</span>
3736
- <a id="__codelineno-0-225" name="__codelineno-0-225"></a>
3737
- <a id="__codelineno-0-226" name="__codelineno-0-226"></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>
3738
- <a id="__codelineno-0-227" name="__codelineno-0-227"></a>
3739
- <a id="__codelineno-0-228" name="__codelineno-0-228"></a> <span class="c1"># Enforce version constraints</span>
3740
- <a id="__codelineno-0-229" name="__codelineno-0-229"></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>
3741
- <a id="__codelineno-0-230" name="__codelineno-0-230"></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>
3742
- <a id="__codelineno-0-231" name="__codelineno-0-231"></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>
3743
- <a id="__codelineno-0-232" name="__codelineno-0-232"></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>
3744
- <a id="__codelineno-0-233" name="__codelineno-0-233"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3745
- <a id="__codelineno-0-234" name="__codelineno-0-234"></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>
3746
- <a id="__codelineno-0-235" name="__codelineno-0-235"></a> <span class="p">)</span>
3747
- <a id="__codelineno-0-236" name="__codelineno-0-236"></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>
3748
- <a id="__codelineno-0-237" name="__codelineno-0-237"></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>
3749
- <a id="__codelineno-0-238" name="__codelineno-0-238"></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>
3750
- <a id="__codelineno-0-239" name="__codelineno-0-239"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3751
- <a id="__codelineno-0-240" name="__codelineno-0-240"></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>
3752
- <a id="__codelineno-0-241" name="__codelineno-0-241"></a> <span class="p">)</span>
3753
- <a id="__codelineno-0-242" name="__codelineno-0-242"></a>
3754
- <a id="__codelineno-0-243" name="__codelineno-0-243"></a> <span class="c1"># Mapping of {setting_name: setting_type} used to validate user configs</span>
3755
- <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># TODO(jathan): This is fine for now, but as we expand the functionality</span>
3756
- <a id="__codelineno-0-245" name="__codelineno-0-245"></a> <span class="c1"># of plugins, we&#39;ll need to consider something like pydantic or attrs.</span>
3757
- <a id="__codelineno-0-246" name="__codelineno-0-246"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
3758
- <a id="__codelineno-0-247" name="__codelineno-0-247"></a> <span class="s2">&quot;caching_config&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
3759
- <a id="__codelineno-0-248" name="__codelineno-0-248"></a> <span class="s2">&quot;default_settings&quot;</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span>
3760
- <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="s2">&quot;installed_apps&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3761
- <a id="__codelineno-0-250" name="__codelineno-0-250"></a> <span class="s2">&quot;middleware&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3762
- <a id="__codelineno-0-251" name="__codelineno-0-251"></a> <span class="s2">&quot;required_settings&quot;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
3763
- <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="p">}</span>
3764
- <a id="__codelineno-0-253" name="__codelineno-0-253"></a>
3765
- <a id="__codelineno-0-254" name="__codelineno-0-254"></a> <span class="c1"># Validate user settings</span>
3766
- <a id="__codelineno-0-255" name="__codelineno-0-255"></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>
3767
- <a id="__codelineno-0-256" name="__codelineno-0-256"></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>
3768
- <a id="__codelineno-0-257" name="__codelineno-0-257"></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>
3769
- <a id="__codelineno-0-258" name="__codelineno-0-258"></a>
3770
- <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># Validate the required_settings</span>
3771
- <a id="__codelineno-0-260" name="__codelineno-0-260"></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>
3772
- <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="p">:</span>
3773
- <a id="__codelineno-0-262" name="__codelineno-0-262"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
3774
- <a id="__codelineno-0-263" name="__codelineno-0-263"></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>
3775
- <a id="__codelineno-0-264" name="__codelineno-0-264"></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>
3776
- <a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="p">)</span>
3777
- <a id="__codelineno-0-266" name="__codelineno-0-266"></a>
3778
- <a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="c1"># Apply default configuration values</span>
3779
- <a id="__codelineno-0-268" name="__codelineno-0-268"></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>
3780
- <a id="__codelineno-0-269" name="__codelineno-0-269"></a> <span class="c1"># user_config and constance_config take precedence</span>
3781
- <a id="__codelineno-0-270" name="__codelineno-0-270"></a> <span class="c1"># this is to support legacy apps that supply default_settings and constance_config</span>
3782
- <a id="__codelineno-0-271" name="__codelineno-0-271"></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>
3783
- <a id="__codelineno-0-272" name="__codelineno-0-272"></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>
4888
+ <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>
4889
+ <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>
4890
+ <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>
4891
+ <a id="__codelineno-0-216" name="__codelineno-0-216"></a>
4892
+ <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>
4893
+ <a id="__codelineno-0-218" name="__codelineno-0-218"></a>
4894
+ <a id="__codelineno-0-219" name="__codelineno-0-219"></a> <span class="c1"># Enforce version constraints</span>
4895
+ <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>
4896
+ <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>
4897
+ <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>
4898
+ <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>
4899
+ <a id="__codelineno-0-224" name="__codelineno-0-224"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4900
+ <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>
4901
+ <a id="__codelineno-0-226" name="__codelineno-0-226"></a> <span class="p">)</span>
4902
+ <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>
4903
+ <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>
4904
+ <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>
4905
+ <a id="__codelineno-0-230" name="__codelineno-0-230"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4906
+ <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>
4907
+ <a id="__codelineno-0-232" name="__codelineno-0-232"></a> <span class="p">)</span>
4908
+ <a id="__codelineno-0-233" name="__codelineno-0-233"></a>
4909
+ <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>
4910
+ <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>
4911
+ <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>
4912
+ <a id="__codelineno-0-237" name="__codelineno-0-237"></a> <span class="n">setting_validations</span> <span class="o">=</span> <span class="p">{</span>
4913
+ <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>
4914
+ <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>
4915
+ <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>
4916
+ <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>
4917
+ <a id="__codelineno-0-242" name="__codelineno-0-242"></a> <span class="p">}</span>
4918
+ <a id="__codelineno-0-243" name="__codelineno-0-243"></a>
4919
+ <a id="__codelineno-0-244" name="__codelineno-0-244"></a> <span class="c1"># Validate user settings</span>
4920
+ <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>
4921
+ <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>
4922
+ <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>
4923
+ <a id="__codelineno-0-248" name="__codelineno-0-248"></a>
4924
+ <a id="__codelineno-0-249" name="__codelineno-0-249"></a> <span class="c1"># Validate the required_settings</span>
4925
+ <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>
4926
+ <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>
4927
+ <a id="__codelineno-0-252" name="__codelineno-0-252"></a> <span class="k">raise</span> <span class="n">PluginImproperlyConfigured</span><span class="p">(</span>
4928
+ <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>
4929
+ <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>
4930
+ <a id="__codelineno-0-255" name="__codelineno-0-255"></a> <span class="p">)</span>
4931
+ <a id="__codelineno-0-256" name="__codelineno-0-256"></a>
4932
+ <a id="__codelineno-0-257" name="__codelineno-0-257"></a> <span class="c1"># Apply default configuration values</span>
4933
+ <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>
4934
+ <a id="__codelineno-0-259" name="__codelineno-0-259"></a> <span class="c1"># user_config and constance_config take precedence</span>
4935
+ <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>
4936
+ <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>
4937
+ <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>
3784
4938
  </code></pre></div></td></tr></table></div>
3785
4939
  </details>
3786
4940
  </div>