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

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

Potentially problematic release.


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

Files changed (668) hide show
  1. nautobot/apps/__init__.py +1 -1
  2. nautobot/apps/api.py +8 -8
  3. nautobot/apps/change_logging.py +2 -2
  4. nautobot/apps/choices.py +4 -4
  5. nautobot/apps/events.py +3 -3
  6. nautobot/apps/factory.py +2 -2
  7. nautobot/apps/filters.py +1 -1
  8. nautobot/apps/forms.py +20 -20
  9. nautobot/apps/graphql.py +2 -2
  10. nautobot/apps/jobs.py +8 -8
  11. nautobot/apps/models.py +19 -19
  12. nautobot/apps/tables.py +1 -1
  13. nautobot/apps/testing.py +10 -10
  14. nautobot/apps/ui.py +2 -2
  15. nautobot/apps/utils.py +7 -7
  16. nautobot/apps/views.py +7 -7
  17. nautobot/circuits/api/serializers.py +1 -0
  18. nautobot/circuits/api/views.py +4 -8
  19. nautobot/circuits/tables.py +2 -1
  20. nautobot/circuits/templates/circuits/circuit_create.html +1 -7
  21. nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +43 -0
  22. nautobot/circuits/tests/integration/test_relationships.py +1 -1
  23. nautobot/circuits/views.py +3 -3
  24. nautobot/cloud/api/views.py +6 -10
  25. nautobot/cloud/models.py +1 -1
  26. nautobot/cloud/views.py +0 -16
  27. nautobot/core/api/constants.py +11 -0
  28. nautobot/core/api/fields.py +5 -5
  29. nautobot/core/api/filter_backends.py +3 -9
  30. nautobot/core/api/schema.py +13 -2
  31. nautobot/core/api/serializers.py +40 -34
  32. nautobot/core/api/views.py +56 -4
  33. nautobot/core/apps/__init__.py +0 -5
  34. nautobot/core/celery/log.py +4 -4
  35. nautobot/core/celery/schedulers.py +2 -2
  36. nautobot/core/choices.py +2 -2
  37. nautobot/core/events/__init__.py +3 -3
  38. nautobot/core/filters.py +67 -35
  39. nautobot/core/forms/__init__.py +19 -19
  40. nautobot/core/forms/fields.py +14 -11
  41. nautobot/core/forms/forms.py +33 -2
  42. nautobot/core/graphql/types.py +1 -1
  43. nautobot/core/jobs/__init__.py +28 -7
  44. nautobot/core/jobs/bulk_actions.py +285 -0
  45. nautobot/core/jobs/cleanup.py +48 -12
  46. nautobot/core/jobs/groups.py +1 -1
  47. nautobot/core/management/commands/validate_models.py +1 -1
  48. nautobot/core/models/__init__.py +3 -1
  49. nautobot/core/models/query_functions.py +2 -2
  50. nautobot/core/models/tree_queries.py +6 -3
  51. nautobot/core/settings.py +29 -2
  52. nautobot/core/settings.yaml +21 -0
  53. nautobot/core/tables.py +79 -61
  54. nautobot/core/templates/about.html +67 -0
  55. nautobot/core/templates/generic/object_bulk_destroy.html +1 -1
  56. nautobot/core/templates/inc/media.html +3 -0
  57. nautobot/core/templates/inc/nav_menu.html +1 -0
  58. nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
  59. nautobot/core/templates/inc/tenant_table_row.html +11 -0
  60. nautobot/core/templates/nautobot_config.py.j2 +13 -0
  61. nautobot/core/templates/search.html +7 -0
  62. nautobot/core/templates/utilities/render_jinja2.html +1 -1
  63. nautobot/core/templates/utilities/templatetags/tag.html +1 -1
  64. nautobot/core/templates/utilities/theme_preview.html +7 -0
  65. nautobot/core/templatetags/helpers.py +11 -2
  66. nautobot/core/testing/__init__.py +8 -8
  67. nautobot/core/testing/api.py +170 -15
  68. nautobot/core/testing/filters.py +45 -10
  69. nautobot/core/testing/forms.py +2 -0
  70. nautobot/core/testing/integration.py +514 -5
  71. nautobot/core/testing/mixins.py +7 -2
  72. nautobot/core/testing/views.py +44 -29
  73. nautobot/core/tests/integration/test_app_home.py +0 -1
  74. nautobot/core/tests/integration/test_app_navbar.py +0 -1
  75. nautobot/core/tests/integration/test_filters.py +0 -2
  76. nautobot/core/tests/integration/test_home.py +0 -1
  77. nautobot/core/tests/integration/test_navbar.py +0 -1
  78. nautobot/core/tests/integration/test_view_authentication.py +1 -0
  79. nautobot/core/tests/runner.py +1 -1
  80. nautobot/core/tests/test_api.py +98 -1
  81. nautobot/core/tests/test_csv.py +25 -3
  82. nautobot/core/tests/test_filters.py +209 -246
  83. nautobot/core/tests/test_forms.py +1 -0
  84. nautobot/core/tests/test_jobs.py +492 -1
  85. nautobot/core/tests/test_models.py +9 -0
  86. nautobot/core/tests/test_settings_schema.py +7 -0
  87. nautobot/core/tests/test_tables.py +100 -0
  88. nautobot/core/tests/test_utils.py +63 -1
  89. nautobot/core/tests/test_views.py +30 -3
  90. nautobot/core/ui/nav.py +1 -0
  91. nautobot/core/ui/object_detail.py +15 -1
  92. nautobot/core/urls.py +11 -0
  93. nautobot/core/utils/git.py +7 -2
  94. nautobot/core/utils/lookup.py +11 -8
  95. nautobot/core/utils/querysets.py +64 -0
  96. nautobot/core/utils/requests.py +24 -9
  97. nautobot/core/views/__init__.py +42 -0
  98. nautobot/core/views/generic.py +131 -197
  99. nautobot/core/views/mixins.py +136 -41
  100. nautobot/core/views/renderers.py +6 -6
  101. nautobot/core/views/utils.py +2 -2
  102. nautobot/dcim/api/serializers.py +56 -64
  103. nautobot/dcim/api/views.py +47 -113
  104. nautobot/dcim/constants.py +6 -13
  105. nautobot/dcim/factory.py +6 -1
  106. nautobot/dcim/filters/__init__.py +31 -2
  107. nautobot/dcim/forms.py +48 -17
  108. nautobot/dcim/graphql/types.py +2 -2
  109. nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
  110. nautobot/dcim/models/__init__.py +1 -1
  111. nautobot/dcim/models/device_component_templates.py +2 -2
  112. nautobot/dcim/models/device_components.py +22 -20
  113. nautobot/dcim/models/devices.py +10 -1
  114. nautobot/dcim/models/locations.py +3 -3
  115. nautobot/dcim/models/power.py +6 -5
  116. nautobot/dcim/models/racks.py +4 -4
  117. nautobot/dcim/tables/__init__.py +3 -3
  118. nautobot/dcim/tables/devices.py +9 -6
  119. nautobot/dcim/tables/devicetypes.py +2 -2
  120. nautobot/dcim/tables/racks.py +1 -1
  121. nautobot/dcim/templates/dcim/cable.html +1 -1
  122. nautobot/dcim/templates/dcim/controller_create.html +1 -7
  123. nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
  124. nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
  125. nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
  126. nautobot/dcim/templates/dcim/device/base.html +1 -1
  127. nautobot/dcim/templates/dcim/device.html +3 -11
  128. nautobot/dcim/templates/dcim/device_component.html +1 -1
  129. nautobot/dcim/templates/dcim/device_edit.html +36 -37
  130. nautobot/dcim/templates/dcim/devicetype.html +1 -1
  131. nautobot/dcim/templates/dcim/location.html +2 -10
  132. nautobot/dcim/templates/dcim/location_edit.html +1 -7
  133. nautobot/dcim/templates/dcim/locationtype.html +1 -1
  134. nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -1
  135. nautobot/dcim/templates/dcim/manufacturer.html +1 -1
  136. nautobot/dcim/templates/dcim/platform.html +1 -1
  137. nautobot/dcim/templates/dcim/powerfeed.html +1 -1
  138. nautobot/dcim/templates/dcim/powerpanel.html +1 -1
  139. nautobot/dcim/templates/dcim/rack.html +2 -10
  140. nautobot/dcim/templates/dcim/rack_edit.html +1 -7
  141. nautobot/dcim/templates/dcim/rackgroup.html +1 -1
  142. nautobot/dcim/templates/dcim/rackreservation.html +3 -11
  143. nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
  144. nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
  145. nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
  146. nautobot/dcim/tests/integration/test_controller.py +62 -0
  147. nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
  148. nautobot/dcim/tests/integration/test_device_bulk_operations.py +30 -0
  149. nautobot/dcim/tests/integration/test_location_bulk_operations.py +43 -0
  150. nautobot/dcim/tests/test_api.py +16 -5
  151. nautobot/dcim/tests/test_filters.py +33 -0
  152. nautobot/dcim/tests/test_forms.py +51 -2
  153. nautobot/dcim/tests/test_graphql.py +52 -0
  154. nautobot/dcim/tests/test_jobs.py +118 -0
  155. nautobot/dcim/tests/test_models.py +52 -9
  156. nautobot/dcim/tests/test_views.py +30 -84
  157. nautobot/dcim/views.py +13 -28
  158. nautobot/extras/api/customfields.py +2 -2
  159. nautobot/extras/api/serializers.py +123 -85
  160. nautobot/extras/api/views.py +33 -30
  161. nautobot/extras/constants.py +3 -0
  162. nautobot/extras/datasources/git.py +125 -0
  163. nautobot/extras/filters/__init__.py +8 -6
  164. nautobot/extras/forms/base.py +2 -2
  165. nautobot/extras/forms/forms.py +139 -31
  166. nautobot/extras/forms/mixins.py +14 -6
  167. nautobot/extras/group_sync.py +3 -3
  168. nautobot/extras/health_checks.py +1 -2
  169. nautobot/extras/jobs.py +85 -18
  170. nautobot/extras/managers.py +3 -1
  171. nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
  172. nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
  173. nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
  174. nautobot/extras/migrations/0122_add_graphqlquery_owner_content_type.py +34 -0
  175. nautobot/extras/models/__init__.py +1 -1
  176. nautobot/extras/models/contacts.py +1 -1
  177. nautobot/extras/models/customfields.py +41 -23
  178. nautobot/extras/models/datasources.py +85 -0
  179. nautobot/extras/models/groups.py +11 -9
  180. nautobot/extras/models/jobs.py +23 -4
  181. nautobot/extras/models/models.py +17 -2
  182. nautobot/extras/models/relationships.py +17 -5
  183. nautobot/extras/plugins/__init__.py +13 -2
  184. nautobot/extras/plugins/marketplace_manifest.yml +84 -79
  185. nautobot/extras/plugins/tables.py +16 -14
  186. nautobot/extras/plugins/views.py +65 -69
  187. nautobot/extras/registry.py +1 -1
  188. nautobot/extras/secrets/__init__.py +2 -2
  189. nautobot/extras/signals.py +15 -1
  190. nautobot/extras/tables.py +7 -5
  191. nautobot/extras/templates/extras/computedfield.html +1 -1
  192. nautobot/extras/templates/extras/configcontext.html +1 -1
  193. nautobot/extras/templates/extras/configcontextschema.html +1 -1
  194. nautobot/extras/templates/extras/customfield.html +1 -1
  195. nautobot/extras/templates/extras/customlink.html +1 -1
  196. nautobot/extras/templates/extras/dynamicgroup.html +2 -10
  197. nautobot/extras/templates/extras/exporttemplate.html +1 -1
  198. nautobot/extras/templates/extras/gitrepository.html +1 -1
  199. nautobot/extras/templates/extras/graphqlquery.html +1 -1
  200. nautobot/extras/templates/extras/job_detail.html +17 -1
  201. nautobot/extras/templates/extras/job_edit.html +1 -0
  202. nautobot/extras/templates/extras/jobbutton_retrieve.html +1 -1
  203. nautobot/extras/templates/extras/jobhook.html +1 -1
  204. nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
  205. nautobot/extras/templates/extras/jobresult.html +1 -1
  206. nautobot/extras/templates/extras/marketplace.html +29 -11
  207. nautobot/extras/templates/extras/objectchange.html +1 -1
  208. nautobot/extras/templates/extras/plugin_detail.html +33 -16
  209. nautobot/extras/templates/extras/plugins_tiles.html +21 -10
  210. nautobot/extras/templates/extras/relationship.html +1 -63
  211. nautobot/extras/templates/extras/role_retrieve.html +1 -1
  212. nautobot/extras/templates/extras/scheduledjob.html +1 -1
  213. nautobot/extras/templates/extras/secret.html +1 -1
  214. nautobot/extras/templates/extras/secretsgroup.html +1 -1
  215. nautobot/extras/templates/extras/status.html +1 -1
  216. nautobot/extras/templates/extras/tag.html +1 -1
  217. nautobot/extras/templates/extras/webhook.html +1 -1
  218. nautobot/extras/templatetags/job_buttons.py +4 -4
  219. nautobot/extras/test_jobs/api_test_job.py +1 -1
  220. nautobot/extras/test_jobs/atomic_transaction.py +2 -2
  221. nautobot/extras/test_jobs/dry_run.py +1 -1
  222. nautobot/extras/test_jobs/fail.py +5 -5
  223. nautobot/extras/test_jobs/file_output.py +1 -1
  224. nautobot/extras/test_jobs/file_upload_fail.py +1 -1
  225. nautobot/extras/test_jobs/file_upload_pass.py +1 -1
  226. nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
  227. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
  228. nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
  229. nautobot/extras/test_jobs/log_redaction.py +1 -1
  230. nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
  231. nautobot/extras/test_jobs/modify_db.py +1 -1
  232. nautobot/extras/test_jobs/object_var_optional.py +1 -1
  233. nautobot/extras/test_jobs/object_var_required.py +1 -1
  234. nautobot/extras/test_jobs/object_vars.py +1 -1
  235. nautobot/extras/test_jobs/pass.py +3 -3
  236. nautobot/extras/test_jobs/profiling.py +1 -1
  237. nautobot/extras/test_jobs/relative_import.py +3 -3
  238. nautobot/extras/test_jobs/singleton.py +16 -0
  239. nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
  240. nautobot/extras/test_jobs/task_queues.py +1 -1
  241. nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_interfaces.gql +8 -0
  242. nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_names.gql +5 -0
  243. nautobot/extras/tests/git_data/02-invalid-files/graphql_queries/bad_device_names.gql +5 -0
  244. nautobot/extras/tests/git_helper.py +9 -1
  245. nautobot/extras/tests/integration/__init__.py +29 -16
  246. nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
  247. nautobot/extras/tests/test_api.py +19 -13
  248. nautobot/extras/tests/test_customfields.py +50 -52
  249. nautobot/extras/tests/test_datasources.py +29 -1
  250. nautobot/extras/tests/test_dynamicgroups.py +1 -1
  251. nautobot/extras/tests/test_filters.py +6 -6
  252. nautobot/extras/tests/test_forms.py +33 -1
  253. nautobot/extras/tests/test_jobs.py +178 -32
  254. nautobot/extras/tests/test_models.py +299 -10
  255. nautobot/extras/tests/test_plugins.py +62 -9
  256. nautobot/extras/tests/test_relationships.py +120 -9
  257. nautobot/extras/tests/test_utils.py +22 -1
  258. nautobot/extras/tests/test_views.py +56 -194
  259. nautobot/extras/utils.py +20 -10
  260. nautobot/extras/views.py +85 -110
  261. nautobot/ipam/api/fields.py +3 -3
  262. nautobot/ipam/api/serializers.py +41 -33
  263. nautobot/ipam/api/views.py +68 -117
  264. nautobot/ipam/factory.py +1 -1
  265. nautobot/ipam/filters.py +3 -2
  266. nautobot/ipam/lookups.py +101 -62
  267. nautobot/ipam/models.py +74 -18
  268. nautobot/ipam/querysets.py +2 -2
  269. nautobot/ipam/tables.py +25 -9
  270. nautobot/ipam/templates/ipam/ipaddress.html +2 -10
  271. nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
  272. nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
  273. nautobot/ipam/templates/ipam/prefix.html +2 -10
  274. nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
  275. nautobot/ipam/templates/ipam/rir.html +1 -1
  276. nautobot/ipam/templates/ipam/routetarget.html +1 -1
  277. nautobot/ipam/templates/ipam/service.html +1 -1
  278. nautobot/ipam/templates/ipam/vlan.html +2 -10
  279. nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
  280. nautobot/ipam/templates/ipam/vlangroup.html +1 -1
  281. nautobot/ipam/templates/ipam/vrf.html +1 -1
  282. nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
  283. nautobot/ipam/tests/test_api.py +436 -3
  284. nautobot/ipam/tests/test_forms.py +49 -47
  285. nautobot/ipam/tests/test_migrations.py +30 -30
  286. nautobot/ipam/tests/test_models.py +119 -34
  287. nautobot/ipam/tests/test_querysets.py +63 -1
  288. nautobot/ipam/tests/test_utils.py +41 -2
  289. nautobot/ipam/tests/test_views.py +3 -0
  290. nautobot/ipam/utils/__init__.py +54 -17
  291. nautobot/ipam/views.py +61 -87
  292. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  293. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  294. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
  295. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  296. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  297. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  298. nautobot/project-static/docs/404.html +131 -14
  299. nautobot/project-static/docs/apps/index.html +131 -14
  300. nautobot/project-static/docs/apps/nautobot-apps.html +132 -16
  301. nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
  302. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.60a45f97.min.js} +2 -2
  303. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.60a45f97.min.js.map} +2 -2
  304. nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js → search.f8cc74c7.min.js} +1 -1
  305. nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js.map → search.f8cc74c7.min.js.map} +1 -1
  306. nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css → main.a40c8224.min.css} +1 -1
  307. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +147 -20
  308. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +144 -17
  309. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +459 -132
  310. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +175 -28
  311. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +180 -31
  312. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +138 -16
  313. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +137 -15
  314. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +164 -27
  315. nautobot/project-static/docs/code-reference/nautobot/apps/events.html +187 -38
  316. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +193 -31
  317. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +216 -48
  318. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +324 -75
  319. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +666 -175
  320. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +194 -46
  321. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +538 -177
  322. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +578 -221
  323. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +145 -18
  324. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +156 -25
  325. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +492 -65
  326. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +705 -215
  327. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +943 -422
  328. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +144 -17
  329. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +619 -200
  330. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +474 -159
  331. nautobot/project-static/docs/development/apps/api/configuration-view.html +131 -14
  332. nautobot/project-static/docs/development/apps/api/database-backend-config.html +131 -14
  333. nautobot/project-static/docs/development/apps/api/models/django-admin.html +131 -14
  334. nautobot/project-static/docs/development/apps/api/models/global-search.html +131 -14
  335. nautobot/project-static/docs/development/apps/api/models/graphql.html +131 -14
  336. nautobot/project-static/docs/development/apps/api/models/index.html +131 -14
  337. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +131 -14
  338. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +131 -14
  339. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +131 -14
  340. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +131 -14
  341. nautobot/project-static/docs/development/apps/api/platform-features/index.html +131 -14
  342. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +131 -14
  343. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +131 -14
  344. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +131 -14
  345. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +131 -14
  346. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +153 -17
  347. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +131 -14
  348. nautobot/project-static/docs/development/apps/api/prometheus.html +131 -14
  349. nautobot/project-static/docs/development/apps/api/setup.html +131 -14
  350. nautobot/project-static/docs/development/apps/api/testing.html +131 -14
  351. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +131 -14
  352. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +131 -14
  353. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +131 -14
  354. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +131 -14
  355. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +131 -14
  356. nautobot/project-static/docs/development/apps/api/views/base-template.html +131 -14
  357. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +131 -14
  358. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +131 -14
  359. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +131 -14
  360. nautobot/project-static/docs/development/apps/api/views/index.html +131 -14
  361. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +131 -14
  362. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +131 -14
  363. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +131 -14
  364. nautobot/project-static/docs/development/apps/api/views/notes.html +131 -14
  365. nautobot/project-static/docs/development/apps/api/views/rest-api.html +137 -16
  366. nautobot/project-static/docs/development/apps/api/views/urls.html +131 -14
  367. nautobot/project-static/docs/development/apps/index.html +131 -14
  368. nautobot/project-static/docs/development/apps/migration/code-updates.html +131 -14
  369. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +131 -14
  370. nautobot/project-static/docs/development/apps/migration/from-v1.html +131 -14
  371. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +131 -14
  372. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +131 -14
  373. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +131 -14
  374. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +131 -14
  375. nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +135 -18
  376. nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +131 -14
  377. nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +297 -25
  378. nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +131 -14
  379. nautobot/project-static/docs/development/apps/porting-from-netbox.html +131 -14
  380. nautobot/project-static/docs/development/core/application-registry.html +131 -14
  381. nautobot/project-static/docs/development/core/best-practices.html +131 -14
  382. nautobot/project-static/docs/development/core/bootstrap-ui.html +131 -14
  383. nautobot/project-static/docs/development/core/caching.html +131 -14
  384. nautobot/project-static/docs/development/core/controllers.html +131 -14
  385. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +158 -84
  386. nautobot/project-static/docs/development/core/generic-views.html +131 -14
  387. nautobot/project-static/docs/development/core/getting-started.html +334 -234
  388. nautobot/project-static/docs/development/core/homepage.html +134 -17
  389. nautobot/project-static/docs/development/core/index.html +131 -14
  390. nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9829 -0
  391. nautobot/project-static/docs/development/core/model-checklist.html +141 -22
  392. nautobot/project-static/docs/development/core/model-features.html +131 -14
  393. nautobot/project-static/docs/development/core/natural-keys.html +131 -14
  394. nautobot/project-static/docs/development/core/navigation-menu.html +131 -14
  395. nautobot/project-static/docs/development/core/release-checklist.html +134 -17
  396. nautobot/project-static/docs/development/core/role-internals.html +131 -14
  397. nautobot/project-static/docs/development/core/settings.html +131 -14
  398. nautobot/project-static/docs/development/core/style-guide.html +134 -17
  399. nautobot/project-static/docs/development/core/templates.html +132 -15
  400. nautobot/project-static/docs/development/core/testing.html +131 -14
  401. nautobot/project-static/docs/development/core/ui-component-framework.html +454 -283
  402. nautobot/project-static/docs/development/core/user-preferences.html +131 -14
  403. nautobot/project-static/docs/development/index.html +131 -14
  404. nautobot/project-static/docs/development/jobs/index.html +301 -132
  405. nautobot/project-static/docs/development/jobs/migration/from-v1.html +131 -14
  406. nautobot/project-static/docs/index.html +139 -33
  407. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
  408. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
  409. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
  410. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
  411. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
  412. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
  413. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
  414. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
  415. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
  416. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
  417. nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
  418. nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
  419. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
  420. nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
  421. nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
  422. nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
  423. nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
  424. nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
  425. nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
  426. nautobot/project-static/docs/objects.inv +0 -0
  427. nautobot/project-static/docs/overview/application_stack.html +132 -17
  428. nautobot/project-static/docs/overview/design_philosophy.html +131 -14
  429. nautobot/project-static/docs/release-notes/index.html +137 -22
  430. nautobot/project-static/docs/release-notes/version-1.0.html +319 -203
  431. nautobot/project-static/docs/release-notes/version-1.1.html +316 -200
  432. nautobot/project-static/docs/release-notes/version-1.2.html +391 -275
  433. nautobot/project-static/docs/release-notes/version-1.3.html +417 -301
  434. nautobot/project-static/docs/release-notes/version-1.4.html +502 -387
  435. nautobot/project-static/docs/release-notes/version-1.5.html +690 -576
  436. nautobot/project-static/docs/release-notes/version-1.6.html +989 -457
  437. nautobot/project-static/docs/release-notes/version-2.0.html +613 -499
  438. nautobot/project-static/docs/release-notes/version-2.1.html +448 -334
  439. nautobot/project-static/docs/release-notes/version-2.2.html +441 -327
  440. nautobot/project-static/docs/release-notes/version-2.3.html +1171 -451
  441. nautobot/project-static/docs/release-notes/version-2.4.html +800 -111
  442. nautobot/project-static/docs/requirements.txt +2 -2
  443. nautobot/project-static/docs/search/search_index.json +1 -1
  444. nautobot/project-static/docs/sitemap.xml +303 -287
  445. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  446. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +131 -14
  447. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +131 -14
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +133 -16
  449. nautobot/project-static/docs/user-guide/administration/configuration/index.html +131 -14
  450. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +131 -14
  451. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +195 -18
  452. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +131 -14
  453. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +134 -17
  454. nautobot/project-static/docs/user-guide/administration/guides/docker.html +131 -14
  455. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +131 -14
  456. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +131 -14
  457. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +131 -14
  458. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +131 -14
  459. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +131 -14
  460. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +133 -16
  461. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +131 -14
  462. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +131 -14
  463. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +131 -14
  464. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +151 -18
  465. nautobot/project-static/docs/user-guide/administration/installation/index.html +131 -14
  466. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +132 -15
  467. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +131 -14
  468. nautobot/project-static/docs/user-guide/administration/installation/services.html +131 -14
  469. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +131 -14
  470. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +131 -14
  471. nautobot/project-static/docs/user-guide/administration/security/index.html +9420 -0
  472. nautobot/project-static/docs/user-guide/administration/security/notices.html +9843 -0
  473. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +131 -14
  474. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +131 -14
  475. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +131 -14
  476. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +131 -14
  477. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +131 -14
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +131 -14
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +131 -14
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +134 -18
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +131 -14
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +131 -14
  483. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +131 -14
  484. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +131 -14
  485. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +131 -14
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +131 -14
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +131 -14
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +131 -14
  489. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +131 -14
  490. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +131 -14
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +131 -14
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +131 -14
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +131 -14
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +131 -14
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +131 -14
  496. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +131 -14
  497. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +131 -14
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +131 -14
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +131 -14
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +131 -14
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +131 -14
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +131 -14
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +131 -14
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +131 -14
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +131 -14
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +131 -14
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +131 -14
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +131 -14
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +131 -14
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +131 -14
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +131 -14
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +131 -14
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +131 -14
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +131 -14
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +131 -14
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +131 -14
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +131 -14
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +131 -14
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +131 -14
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +131 -14
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +131 -14
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +131 -14
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +131 -14
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +131 -14
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +131 -14
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +131 -14
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +131 -14
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +131 -14
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +131 -14
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +131 -14
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +131 -14
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +131 -14
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +131 -14
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +131 -14
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +131 -14
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +131 -14
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +131 -14
  538. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +135 -22
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +131 -14
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +131 -14
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +131 -14
  542. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +131 -14
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +131 -14
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +131 -14
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +131 -14
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +131 -14
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +131 -14
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +131 -14
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +131 -14
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +131 -14
  551. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +134 -17
  552. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +131 -14
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +131 -14
  554. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +131 -14
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +131 -14
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +131 -14
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +131 -14
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +131 -14
  559. nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +131 -14
  560. nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +131 -14
  561. nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +131 -14
  562. nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +131 -14
  563. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +131 -14
  564. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +131 -14
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +131 -14
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +131 -14
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +134 -17
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +131 -14
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +131 -14
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +131 -14
  571. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +131 -14
  572. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +131 -14
  573. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +131 -14
  574. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +236 -34
  575. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +131 -14
  576. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +131 -14
  590. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +131 -14
  591. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +134 -17
  592. nautobot/project-static/docs/{development/core/local-k8s.html → user-guide/feature-guides/wireless-networks-and-controllers.html} +632 -566
  593. nautobot/project-static/docs/user-guide/index.html +131 -14
  594. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +131 -14
  595. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +135 -18
  596. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +131 -14
  597. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +131 -14
  598. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +131 -14
  599. nautobot/project-static/docs/user-guide/platform-functionality/events.html +131 -14
  600. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +131 -14
  601. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +131 -14
  602. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +451 -16
  603. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +131 -14
  604. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +131 -14
  605. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +131 -14
  606. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +135 -17
  607. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +131 -14
  608. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +134 -17
  609. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +131 -14
  610. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +131 -14
  611. nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9797 -0
  612. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +131 -14
  613. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +131 -14
  614. nautobot/project-static/docs/user-guide/platform-functionality/note.html +131 -14
  615. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +131 -14
  616. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +132 -15
  617. nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +131 -14
  618. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +131 -14
  619. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +179 -35
  620. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +159 -15
  621. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +131 -14
  622. nautobot/project-static/docs/user-guide/platform-functionality/role.html +131 -14
  623. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +131 -14
  624. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +131 -14
  625. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +131 -14
  626. nautobot/project-static/docs/user-guide/platform-functionality/status.html +131 -14
  627. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +131 -14
  628. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +131 -14
  629. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +131 -14
  630. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +131 -14
  631. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +131 -14
  632. nautobot/project-static/js/forms.js +1 -1
  633. nautobot/tenancy/api/views.py +9 -13
  634. nautobot/tenancy/templates/tenancy/tenant.html +1 -2
  635. nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
  636. nautobot/tenancy/views.py +4 -2
  637. nautobot/users/admin.py +1 -1
  638. nautobot/users/api/serializers.py +5 -4
  639. nautobot/users/api/views.py +3 -3
  640. nautobot/virtualization/api/serializers.py +4 -4
  641. nautobot/virtualization/api/views.py +5 -24
  642. nautobot/virtualization/filters.py +20 -3
  643. nautobot/virtualization/models.py +1 -1
  644. nautobot/virtualization/tables.py +2 -2
  645. nautobot/virtualization/templates/virtualization/cluster.html +1 -1
  646. nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
  647. nautobot/virtualization/templates/virtualization/clustergroup.html +1 -1
  648. nautobot/virtualization/templates/virtualization/clustertype.html +1 -1
  649. nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -10
  650. nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
  651. nautobot/virtualization/templates/virtualization/vminterface.html +1 -1
  652. nautobot/virtualization/tests/test_filters.py +17 -0
  653. nautobot/wireless/filters.py +2 -2
  654. nautobot/wireless/forms.py +1 -1
  655. nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
  656. nautobot/wireless/tests/integration/__init__.py +0 -0
  657. nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
  658. nautobot/wireless/tests/test_filters.py +29 -1
  659. nautobot/wireless/tests/test_views.py +22 -1
  660. nautobot/wireless/views.py +0 -10
  661. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/METADATA +9 -9
  662. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/RECORD +667 -610
  663. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/WHEEL +1 -1
  664. nautobot/core/fixtures/user-data.json +0 -59
  665. /nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css.map → main.a40c8224.min.css.map} +0 -0
  666. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/LICENSE.txt +0 -0
  667. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/NOTICE +0 -0
  668. {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@
18
18
 
19
19
 
20
20
  <link rel="icon" href="../../assets/favicon.ico">
21
- <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.46">
21
+ <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.50">
22
22
 
23
23
 
24
24
 
@@ -26,7 +26,7 @@
26
26
 
27
27
 
28
28
 
29
- <link rel="stylesheet" href="../../assets/stylesheets/main.6f8fc17f.min.css">
29
+ <link rel="stylesheet" href="../../assets/stylesheets/main.a40c8224.min.css">
30
30
 
31
31
 
32
32
  <link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
@@ -38,7 +38,7 @@
38
38
 
39
39
 
40
40
 
41
- <style>:root{--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M288 0H128c-17.7 0-32 14.3-32 32s14.3 32 32 32v132.8c0 11.8-3.3 23.5-9.5 33.5L10.3 406.2C3.6 417.2 0 429.7 0 442.6 0 480.9 31.1 512 69.4 512h309.2c38.3 0 69.4-31.1 69.4-69.4 0-12.8-3.6-25.4-10.3-36.4L329.5 230.4c-6.2-10.1-9.5-21.7-9.5-33.5V64c17.7 0 32-14.3 32-32S337.7 0 320 0zm-96 196.8V64h64v132.8c0 23.7 6.6 46.9 19 67.1l34.5 56.1h-171l34.5-56.1c12.4-20.2 19-43.4 19-67.1"/></svg>');}</style>
41
+ <style>:root{--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M288 0H128c-17.7 0-32 14.3-32 32s14.3 32 32 32v132.8c0 11.8-3.3 23.5-9.5 33.5L10.3 406.2C3.6 417.2 0 429.7 0 442.6 0 480.9 31.1 512 69.4 512h309.2c38.3 0 69.4-31.1 69.4-69.4 0-12.8-3.6-25.4-10.3-36.4L329.5 230.4c-6.2-10.1-9.5-21.7-9.5-33.5V64c17.7 0 32-14.3 32-32S337.7 0 320 0zm-96 196.8V64h64v132.8c0 23.7 6.6 46.9 19 67.1l34.5 56.1h-171l34.5-56.1c12.4-20.2 19-43.4 19-67.1"/></svg>');}</style>
42
42
 
43
43
 
44
44
 
@@ -217,7 +217,7 @@
217
217
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
218
218
  <div class="md-source__icon md-icon">
219
219
 
220
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
220
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
221
221
  </div>
222
222
  <div class="md-source__repository">
223
223
  GitHub
@@ -377,7 +377,7 @@
377
377
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
378
378
  <div class="md-source__icon md-icon">
379
379
 
380
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
380
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
381
381
  </div>
382
382
  <div class="md-source__repository">
383
383
  GitHub
@@ -1697,6 +1697,81 @@
1697
1697
 
1698
1698
 
1699
1699
 
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+
1708
+
1709
+
1710
+
1711
+
1712
+
1713
+ <li class="md-nav__item md-nav__item--nested">
1714
+
1715
+
1716
+
1717
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_1_7" >
1718
+
1719
+
1720
+
1721
+ <div class="md-nav__link md-nav__container">
1722
+ <a href="../../user-guide/administration/security/index.html" class="md-nav__link ">
1723
+
1724
+
1725
+ <span class="md-ellipsis">
1726
+ Security
1727
+ </span>
1728
+
1729
+
1730
+ </a>
1731
+
1732
+
1733
+ <label class="md-nav__link " for="__nav_2_1_7" id="__nav_2_1_7_label" tabindex="0">
1734
+ <span class="md-nav__icon md-icon"></span>
1735
+ </label>
1736
+
1737
+ </div>
1738
+
1739
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_1_7_label" aria-expanded="false">
1740
+ <label class="md-nav__title" for="__nav_2_1_7">
1741
+ <span class="md-nav__icon md-icon"></span>
1742
+ Security
1743
+ </label>
1744
+ <ul class="md-nav__list" data-md-scrollfix>
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+
1751
+
1752
+ <li class="md-nav__item">
1753
+ <a href="../../user-guide/administration/security/notices.html" class="md-nav__link">
1754
+
1755
+
1756
+ <span class="md-ellipsis">
1757
+ Notices
1758
+ </span>
1759
+
1760
+
1761
+ </a>
1762
+ </li>
1763
+
1764
+
1765
+
1766
+
1767
+ </ul>
1768
+ </nav>
1769
+
1770
+ </li>
1771
+
1772
+
1773
+
1774
+
1700
1775
  </ul>
1701
1776
  </nav>
1702
1777
 
@@ -2112,6 +2187,27 @@
2112
2187
 
2113
2188
 
2114
2189
 
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+ <li class="md-nav__item">
2197
+ <a href="../../user-guide/feature-guides/wireless-networks-and-controllers.html" class="md-nav__link">
2198
+
2199
+
2200
+ <span class="md-ellipsis">
2201
+ Wireless Networks and Controllers
2202
+ </span>
2203
+
2204
+
2205
+ </a>
2206
+ </li>
2207
+
2208
+
2209
+
2210
+
2115
2211
  </ul>
2116
2212
  </nav>
2117
2213
 
@@ -5131,6 +5227,27 @@
5131
5227
 
5132
5228
 
5133
5229
 
5230
+ <li class="md-nav__item">
5231
+ <a href="../../user-guide/platform-functionality/jobs/kubernetes-job-support.html" class="md-nav__link">
5232
+
5233
+
5234
+ <span class="md-ellipsis">
5235
+ Kubernetes Job Support
5236
+ </span>
5237
+
5238
+
5239
+ </a>
5240
+ </li>
5241
+
5242
+
5243
+
5244
+
5245
+
5246
+
5247
+
5248
+
5249
+
5250
+
5134
5251
  <li class="md-nav__item">
5135
5252
  <a href="../../user-guide/platform-functionality/jobs/jobbutton.html" class="md-nav__link">
5136
5253
 
@@ -8062,11 +8179,11 @@
8062
8179
 
8063
8180
 
8064
8181
  <li class="md-nav__item">
8065
- <a href="../core/local-k8s.html" class="md-nav__link">
8182
+ <a href="../core/minikube-dev-environment-for-k8s-jobs.html" class="md-nav__link">
8066
8183
 
8067
8184
 
8068
8185
  <span class="md-ellipsis">
8069
- Local Kubernetes Cluster
8186
+ Minikube Dev Environment for K8s Jobs
8070
8187
  </span>
8071
8188
 
8072
8189
 
@@ -9010,6 +9127,15 @@
9010
9127
  <nav class="md-nav" aria-label="Writing Jobs">
9011
9128
  <ul class="md-nav__list">
9012
9129
 
9130
+ <li class="md-nav__item">
9131
+ <a href="#introduction-to-writing-jobs" class="md-nav__link">
9132
+ <span class="md-ellipsis">
9133
+ Introduction to Writing Jobs
9134
+ </span>
9135
+ </a>
9136
+
9137
+ </li>
9138
+
9013
9139
  <li class="md-nav__item">
9014
9140
  <a href="#job-registration" class="md-nav__link">
9015
9141
  <span class="md-ellipsis">
@@ -9147,6 +9273,15 @@
9147
9273
  </span>
9148
9274
  </a>
9149
9275
 
9276
+ </li>
9277
+
9278
+ <li class="md-nav__item">
9279
+ <a href="#is_singleton" class="md-nav__link">
9280
+ <span class="md-ellipsis">
9281
+ is_singleton
9282
+ </span>
9283
+ </a>
9284
+
9150
9285
  </li>
9151
9286
 
9152
9287
  <li class="md-nav__item">
@@ -9471,11 +9606,11 @@
9471
9606
  <li class="md-nav__item">
9472
9607
  <a href="#debugging-job-performance" class="md-nav__link">
9473
9608
  <span class="md-ellipsis">
9474
- Debugging job performance
9609
+ Debugging Job Performance
9475
9610
  </span>
9476
9611
  </a>
9477
9612
 
9478
- <nav class="md-nav" aria-label="Debugging job performance">
9613
+ <nav class="md-nav" aria-label="Debugging Job Performance">
9479
9614
  <ul class="md-nav__list">
9480
9615
 
9481
9616
  <li class="md-nav__item">
@@ -9502,6 +9637,15 @@
9502
9637
  <nav class="md-nav" aria-label="Example Jobs">
9503
9638
  <ul class="md-nav__list">
9504
9639
 
9640
+ <li class="md-nav__item">
9641
+ <a href="#example-everything-job" class="md-nav__link">
9642
+ <span class="md-ellipsis">
9643
+ Example "Everything" Job
9644
+ </span>
9645
+ </a>
9646
+
9647
+ </li>
9648
+
9505
9649
  <li class="md-nav__item">
9506
9650
  <a href="#creating-objects-for-a-planned-location" class="md-nav__link">
9507
9651
  <span class="md-ellipsis">
@@ -9620,30 +9764,24 @@
9620
9764
 
9621
9765
  <h1 id="jobs">Jobs<a class="headerlink" href="#jobs" title="Permanent link">&para;</a></h1>
9622
9766
  <p>Familiarity with the basic concepts of <a href="../../user-guide/platform-functionality/jobs/index.html">Jobs</a>, especially the distinction between Job classes (Python code) and Job records (Nautobot database records), is recommended before authoring your first Job.</p>
9623
- <div class="admonition tip">
9624
- <p class="admonition-title">Tip</p>
9767
+ <details class="tip">
9768
+ <summary>More about Job class source code loading</summary>
9625
9769
  <p>From a development standpoint, it's especially important to understand that the Job database record never stores the Job class code. It only describes the <strong>existence</strong> of a Job class. The actual Job class source code is loaded into memory only.</p>
9626
- </div>
9627
- <div class="admonition info">
9628
- <p class="admonition-title">Info</p>
9629
9770
  <p>As an implementation detail in Nautobot 2.2.3 and later, all known Job <strong>classes</strong> are cached in the <a href="../core/application-registry.html#jobs">application registry</a>, which is refreshed at various times including Nautobot application startup and immediately prior to actually executing any given Job by a worker. This implementation detail should not be relied on directly; instead you should always use the <code>get_job()</code> and/or <code>get_jobs()</code> APIs to obtain a Job class when needed.</p>
9630
- </div>
9631
- <h2 id="migrating-jobs-from-v1-to-v2">Migrating Jobs from v1 to v2<a class="headerlink" href="#migrating-jobs-from-v1-to-v2" title="Permanent link">&para;</a></h2>
9632
- <details class="version-changed">
9633
- <summary>Changed in version 2.0.0</summary>
9634
- <p>See <a href="migration/from-v1.html">Migrating Jobs From Nautobot v1</a> for more information on how to migrate your existing jobs to Nautobot v2.</p>
9635
9771
  </details>
9772
+ <h2 id="migrating-jobs-from-v1-to-v2">Migrating Jobs from v1 to v2<a class="headerlink" href="#migrating-jobs-from-v1-to-v2" title="Permanent link">&para;</a></h2>
9773
+ <p>See <a href="migration/from-v1.html">Migrating Jobs From Nautobot v1</a> for more information on how to migrate your existing Jobs to Nautobot v2.</p>
9636
9774
  <h2 id="installing-jobs">Installing Jobs<a class="headerlink" href="#installing-jobs" title="Permanent link">&para;</a></h2>
9637
9775
  <p>Jobs may be installed in one of three ways:</p>
9638
9776
  <ul>
9639
9777
  <li>Manually installed as files in the <a href="../../user-guide/administration/configuration/settings.html#jobs_root"><code>JOBS_ROOT</code></a> path (which defaults to <code>$NAUTOBOT_ROOT/jobs/</code>).<ul>
9640
- <li>Python files and subdirectories containing Python files will be dynamically loaded at Nautobot startup in order to discover and register available Job classes. For example, a job class named <code>MyJobClass</code> in <code>$JOBS_ROOT/my_job.py</code> will be loaded into Nautobot as <code>my_job.MyJobClass</code>.</li>
9778
+ <li>Python files and subdirectories containing Python files will be dynamically loaded at Nautobot startup in order to discover and register available Job classes. For example, a Job class named <code>MyJobClass</code> in <code>$JOBS_ROOT/my_job.py</code> will be loaded into Nautobot as <code>my_job.MyJobClass</code>.</li>
9641
9779
  <li>All Python modules in this directory are imported by Nautobot and all worker processes at startup. If you have a <code>custom_jobs.py</code> and a <code>custom_jobs_module/__init__.py</code> file in your <code>JOBS_ROOT</code>, both of these files will be imported at startup.</li>
9642
9780
  </ul>
9643
9781
  </li>
9644
9782
  <li>Imported from an external <a href="../../user-guide/platform-functionality/gitrepository.html#jobs">Git repository</a>.<ul>
9645
- <li>Git repositories are loaded into the module namespace of the <code>GitRepository.slug</code> value at startup. For example, if your <code>slug</code> value is <code>my_git_jobs</code> your jobs will be loaded into Python as <code>my_git_jobs.jobs.MyJobClass</code>.</li>
9646
- <li>All git repositories providing jobs must include a <code>__init__.py</code> file at the root of the repository.</li>
9783
+ <li>Git repositories are loaded into the module namespace of the <code>GitRepository.slug</code> value at startup. For example, if your <code>slug</code> value is <code>my_git_jobs</code> your Jobs will be loaded into Python as <code>my_git_jobs.jobs.MyJobClass</code>.</li>
9784
+ <li>All git repositories providing Jobs must include a <code>__init__.py</code> file at the root of the repository.</li>
9647
9785
  <li>Nautobot and all worker processes will import the git repository's <code>jobs</code> module at startup so a <code>jobs.py</code> or <code>jobs/__init__.py</code> file must exist in the root of the repository.</li>
9648
9786
  </ul>
9649
9787
  </li>
@@ -9652,50 +9790,59 @@
9652
9790
  </ul>
9653
9791
  </li>
9654
9792
  </ul>
9655
- <p>In any case, each module holds one or more Job classes (Python classes), each of which serves a specific purpose. The logic of each job can be split into a number of distinct methods, each of which performs a discrete portion of the overall job logic.</p>
9656
- <p>For example, we can create a module named <code>devices.py</code> to hold all of our jobs which pertain to devices in Nautobot. Within that module, we might define several jobs. Each job is defined as a Python class inheriting from <code>nautobot.apps.jobs.Job</code>, which provides the base functionality needed to accept user input and log activity.</p>
9793
+ <p>In any case, each module holds one or more Job classes (Python classes), each of which serves a specific purpose. The logic of each Job can be split into a number of distinct methods, each of which performs a discrete portion of the overall Job logic.</p>
9794
+ <p>For example, we can create a module named <code>device_jobs.py</code> to hold all of our Jobs which pertain to devices in Nautobot. Within that module, we might define several Jobs. Each Job is defined as a Python class inheriting from <code>nautobot.apps.jobs.Job</code>, which provides the base functionality needed to accept user input and log activity.</p>
9657
9795
  <details class="version-changed">
9658
- <summary>Changed in version 2.0.0</summary>
9659
- <p>All job classes that are intended to be runnable must now be registered by a call to <code>nautobot.apps.jobs.register_jobs()</code> on module import. This allows for a module to, if desired, define "abstract" base Job classes that are defined in code but are not registered (and therefore are not runnable in Nautobot). The <code>register_jobs</code> method accepts one or more job classes as arguments.</p>
9796
+ <summary>Changed in version 2.0.0 — <code>register_jobs()</code> must be called</summary>
9797
+ <p>All Job classes that are intended to be runnable must now be registered by a call to <code>nautobot.apps.jobs.register_jobs()</code> on module import. This allows for a module to, if desired, define "abstract" base Job classes that are defined in code but are not registered (and therefore are not runnable in Nautobot). The <code>register_jobs</code> method accepts one or more Job classes as arguments.</p>
9660
9798
  </details>
9661
9799
  <h2 id="writing-jobs">Writing Jobs<a class="headerlink" href="#writing-jobs" title="Permanent link">&para;</a></h2>
9800
+ <h3 id="introduction-to-writing-jobs">Introduction to Writing Jobs<a class="headerlink" href="#introduction-to-writing-jobs" title="Permanent link">&para;</a></h3>
9662
9801
  <div class="admonition warning">
9663
9802
  <p class="admonition-title">Warning</p>
9664
- <p>Make sure your Job subclasses inherit from <code>nautobot.apps.Job</code> and <em>not</em> from <code>nautobot.extras.models.Job</code> instead; if you mistakenly inherit from the latter, Django will think you want to define a new database model.</p>
9803
+ <p>Make sure your Job subclasses inherit from <code>nautobot.apps.jobs.Job</code> and <em>not</em> from <code>nautobot.extras.models.Job</code> instead; if you mistakenly inherit from the latter, Django will think you want to define a new database model!</p>
9665
9804
  </div>
9666
- <div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
9805
+ <p>The most basic structure of a Python file providing one or more Jobs is as follows:</p>
9806
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps</span> <span class="kn">import</span> <span class="n">jobs</span>
9667
9807
  <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>
9668
- <a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9669
- <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">...</span>
9670
- <a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>
9671
- <a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a><span class="k">class</span> <span class="nc">DeviceConnectionsReport</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9672
- <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="o">...</span>
9673
- <a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>
9674
- <a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="k">class</span> <span class="nc">DeviceIPsReport</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9675
- <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="o">...</span>
9676
- <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
9677
- <a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">CreateDevices</span><span class="p">,</span> <span class="n">DeviceConnectionsReport</span><span class="p">,</span> <span class="n">DeviceIPsReport</span><span class="p">)</span>
9808
+ <a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;My Group Of Jobs&quot;</span> <span class="c1"># optional, but recommended to define a grouping name</span>
9809
+ <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>
9810
+ <a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a><span class="k">class</span> <span class="nc">MyNewJob</span><span class="p">(</span><span class="n">jobs</span><span class="o">.</span><span class="n">Job</span><span class="p">):</span>
9811
+ <a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9812
+ <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="c1"># metadata attributes go here</span>
9813
+ <a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;My New Job&quot;</span>
9814
+ <a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="c1"># ... etc.</span>
9815
+ <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>
9816
+ <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="c1"># input variable definitions go here</span>
9817
+ <a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> <span class="n">some_text_input</span> <span class="o">=</span> <span class="n">jobs</span><span class="o">.</span><span class="n">StringVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9818
+ <a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="c1"># ... etc.</span>
9819
+ <a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a>
9820
+ <a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">some_text_input</span><span class="p">,</span> <span class="o">...</span><span class="p">):</span>
9821
+ <a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="c1"># code to execute when the Job is run goes here</span>
9822
+ <a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;some_text_input: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">some_text_input</span><span class="p">)</span>
9823
+ <a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a>
9824
+ <a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a><span class="n">jobs</span><span class="o">.</span><span class="n">register_jobs</span><span class="p">(</span><span class="n">MyNewJob</span><span class="p">)</span>
9678
9825
  </code></pre></div>
9679
- <p>Each job class will implement some or all of the following components:</p>
9826
+ <p>Each Job class will implement some or all of the following components:</p>
9680
9827
  <ul>
9681
- <li>Module and class attributes, providing for default behavior, documentation and discoverability</li>
9682
- <li>a set of variables for user input via the Nautobot UI (if your job requires any user inputs)</li>
9683
- <li>a <code>run()</code> method, which is the only required attribute on a Job class and receives the user input values, if any, as keyword arguments.</li>
9684
- <li>Optionally, any of the special methods <code>before_start()</code>, <code>on_success()</code>, <code>on_failure()</code>, and/or <code>after_return()</code> (more on these later).</li>
9828
+ <li><a href="#module-metadata-attributes">Module</a> and class <a href="#class-metadata-attributes">metadata attributes</a>, configuring the system-level behavior of the Job and providing for documentation and discoverability by users.</li>
9829
+ <li>A set of <a href="#variables">variables</a> for user input via the Nautobot UI or API.</li>
9830
+ <li>The <a href="#the-run-method"><code>run()</code> method</a>, which is the only <strong>required</strong> attribute on a Job class and receives the user input values as keyword arguments.</li>
9831
+ <li>Optionally, any of the special methods <a href="#the-before_start-method"><code>before_start()</code></a>, <a href="#the-on_success-method"><code>on_success()</code></a>, <a href="#the-on_failure-method"><code>on_failure()</code></a>, and/or <a href="#the-after_return-method"><code>after_return()</code></a>.</li>
9685
9832
  </ul>
9686
- <p>It's important to understand that jobs execute on the server asynchronously as background tasks; they log messages and report their status to the database by updating <a href="../../user-guide/platform-functionality/jobs/models.html#job-results"><code>JobResult</code></a> records and creating <a href="../../user-guide/platform-functionality/jobs/models.html#job-log-entry"><code>JobLogEntry</code></a> records.</p>
9833
+ <p>It's important to understand that Jobs execute on the server asynchronously as background tasks; they log messages and report their status to the database by updating <a href="../../user-guide/platform-functionality/jobs/models.html#job-results"><code>JobResult</code></a> records and creating <a href="../../user-guide/platform-functionality/jobs/models.html#job-log-entry"><code>JobLogEntry</code></a> records.</p>
9687
9834
  <div class="admonition note">
9688
- <p class="admonition-title">Note</p>
9835
+ <p class="admonition-title">About detection of changes while developing a Job</p>
9689
9836
  <p>When actively developing a Job utilizing a development environment it's important to understand that the "automatically reload when code changes are detected" debugging functionality provided by <code>nautobot-server runserver</code> does <strong>not</strong> automatically restart the Celery <code>worker</code> process when code changes are made; therefore, it is required to restart the <code>worker</code> after each update to your Job source code or else it will continue to run the version of the Job code that was present when it first started. In the Nautobot core development environment, we use <code>watchmedo auto-restart</code> as a helper tool to auto-restart the workers as well on code changes; you may wish to configure your local development environment similarly for convenience.</p>
9690
9837
  <p>Additionally, as of Nautobot 1.3, the Job database records corresponding to installed Jobs are <em>not</em> automatically refreshed when the development server auto-restarts. If you make changes to any of the class and module metadata attributes described in the following sections, the database will be refreshed to reflect these changes only after running <code>nautobot-server migrate</code> or <code>nautobot-server post_upgrade</code> (recommended) or if you manually edit a Job database record to force it to be refreshed. The exception here is Git-repository-provided Jobs; resyncing the Git repository through Nautobot will also trigger a refresh of the Job records corresponding to this repository's contents.</p>
9691
9838
  </div>
9692
9839
  <h3 id="job-registration">Job Registration<a class="headerlink" href="#job-registration" title="Permanent link">&para;</a></h3>
9693
9840
  <details class="version-changed">
9694
- <summary>Changed in version 2.0.0</summary>
9841
+ <summary>Changed in version 2.0.0 — <code>register_jobs()</code> is now required</summary>
9695
9842
  </details>
9696
- <p>All Job classes, including <code>JobHookReceiver</code> and <code>JobButtonReceiver</code> classes must be registered at <strong>import time</strong> using the <code>nautobot.apps.jobs.register_jobs</code> method. This method accepts one or more job classes as arguments. You must account for how your jobs are imported when deciding where to call this method.</p>
9843
+ <p>All Job classes, including <code>JobHookReceiver</code> and <code>JobButtonReceiver</code> classes must be registered at <strong>import time</strong> using the <code>nautobot.apps.jobs.register_jobs</code> method. This method accepts one or more Job classes as arguments. You must account for how your Jobs are imported when deciding where to call this method.</p>
9697
9844
  <h4 id="registering-jobs-in-jobs_root-or-git-repositories">Registering Jobs in <code>JOBS_ROOT</code> or Git Repositories<a class="headerlink" href="#registering-jobs-in-jobs_root-or-git-repositories" title="Permanent link">&para;</a></h4>
9698
- <p>Only top level module names within <code>JOBS_ROOT</code> are imported by Nautobot at runtime. This means that if you're using submodules, you need to ensure that your jobs are either registered in your top level <code>__init__.py</code> or that this file imports your submodules where the jobs are registered:</p>
9845
+ <p>Only top level module names within <code>JOBS_ROOT</code> are imported by Nautobot at runtime. This means that if you're using submodules, you need to ensure that your Jobs are either registered in your top level <code>__init__.py</code> or that this file imports your submodules where the Jobs are registered:</p>
9699
9846
  <div class="highlight"><span class="filename">$JOBS_ROOT/my_jobs/__init__.py</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">my_job_module</span>
9700
9847
  </code></pre></div>
9701
9848
  <div class="highlight"><span class="filename">$JOBS_ROOT/my_jobs/my_job_module.py</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
@@ -9705,12 +9852,12 @@
9705
9852
  <a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a>
9706
9853
  <a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">MyJob</span><span class="p">)</span>
9707
9854
  </code></pre></div>
9708
- <p>Similarly, only the <code>jobs</code> module is loaded from Git repositories. If you're using submodules, you need to ensure that your jobs are either registered in the repository's <code>jobs/__init__.py</code> or that this file imports your submodules where the jobs are registered.</p>
9709
- <p>If not using submodules, you should register your job in the file where your job is defined.</p>
9710
- <p>Examples of the different directory structures when registering jobs in Git repositories:</p>
9855
+ <p>Similarly, only the <code>jobs</code> module is loaded from Git repositories. If you're using submodules, you need to ensure that your Jobs are either registered in the repository's <code>jobs/__init__.py</code> or that this file imports your submodules where the Jobs are registered.</p>
9856
+ <p>If not using submodules, you should register your Job in the file where it is defined.</p>
9857
+ <p>Examples of the different directory structures when registering Jobs in Git repositories:</p>
9711
9858
  <div class="admonition note">
9712
- <p class="admonition-title">Note</p>
9713
- <p>Take note of the <code>__init__.py</code> at the root of the repository. This is required to register jobs in a Git repository.</p>
9859
+ <p class="admonition-title"><code>__init__.py</code></p>
9860
+ <p>Take note of the <code>__init__.py</code> at the root of the repository. This is required to register Jobs in a Git repository.</p>
9714
9861
  </div>
9715
9862
  <div class="highlight"><span class="filename">jobs.py</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>.
9716
9863
  <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>├── __init__.py
@@ -9723,14 +9870,14 @@
9723
9870
  <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> └── my_job_module.py
9724
9871
  </code></pre></div>
9725
9872
  <h4 id="registering-jobs-in-an-app">Registering Jobs in an App<a class="headerlink" href="#registering-jobs-in-an-app" title="Permanent link">&para;</a></h4>
9726
- <p>Apps should register jobs in the module defined in their <a href="../apps/api/nautobot-app-config.html#nautobotappconfig-code-location-attributes"><code>NautobotAppConfig.jobs</code></a> property. This defaults to the <code>jobs</code> module of the App.</p>
9873
+ <p>Apps should register Jobs in the module defined in their <a href="../apps/api/nautobot-app-config.html#nautobotappconfig-code-location-attributes"><code>NautobotAppConfig.jobs</code></a> property. This defaults to the <code>jobs</code> module of the App.</p>
9727
9874
  <h3 id="reserved-attribute-names">Reserved Attribute Names<a class="headerlink" href="#reserved-attribute-names" title="Permanent link">&para;</a></h3>
9728
9875
  <p>There are many attributes and methods of the Job class that serve as reserved names. You must be careful when implementing custom methods or defining the user input <a href="#variables">variables</a> for your Job that you do not inadvertently "step on" one of these reserved attributes causing unexpected behavior or errors.</p>
9729
9876
  <div class="admonition example">
9730
9877
  <p class="admonition-title">Example</p>
9731
9878
  <p>One classic pitfall here is the the reserved <code>name</code> metadata attribute - if you attempt to redefine <code>name</code> as a user input variable, your Job will not work.</p>
9732
9879
  </div>
9733
- <p>As of Nautobot 2.2.3, the current list of reserved names (not including low-level Python built-ins such as <code>__dict__</code> or <code>__str__</code> includes:</p>
9880
+ <p>As of Nautobot 2.4.0, the current list of reserved names (not including low-level Python built-ins such as <code>__dict__</code> or <code>__str__</code> includes:</p>
9734
9881
  <table>
9735
9882
  <thead>
9736
9883
  <tr>
@@ -9816,6 +9963,10 @@
9816
9963
  <td><a href="#hidden">metadata property</a></td>
9817
9964
  </tr>
9818
9965
  <tr>
9966
+ <td><code>is_singleton</code></td>
9967
+ <td><a href="#is_singleton">metadata property</a></td>
9968
+ </tr>
9969
+ <tr>
9819
9970
  <td><code>job_model</code></td>
9820
9971
  <td>property</td>
9821
9972
  </tr>
@@ -9903,21 +10054,21 @@
9903
10054
  </table>
9904
10055
  <h3 id="module-metadata-attributes">Module Metadata Attributes<a class="headerlink" href="#module-metadata-attributes" title="Permanent link">&para;</a></h3>
9905
10056
  <h4 id="name-grouping"><code>name</code> (Grouping)<a class="headerlink" href="#name-grouping" title="Permanent link">&para;</a></h4>
9906
- <p>You can define a global constant called <code>name</code> within a job module (the Python file which contains one or more job classes) to set the default grouping under which jobs in this module will be displayed in the Nautobot UI. If this value is not defined, the module's file name will be used. This "grouping" value may also be defined or overridden when editing Job records in the database.</p>
10057
+ <p>You can define a global constant called <code>name</code> within a job module (the Python file which contains one or more Job classes) to set the default grouping under which the Jobs in this module will be displayed in the Nautobot UI. If this value is not defined, the module's file name will be used. This "grouping" value may also be defined or overridden when editing Job records in the database.</p>
9907
10058
  <div class="admonition note">
9908
10059
  <p class="admonition-title">Note</p>
9909
10060
  <p>In some UI elements and API endpoints, the module file name is displayed in addition to or in place of this attribute, so even if defining this attribute, you should still choose an appropriately explanatory file name as well.</p>
9910
10061
  </div>
9911
10062
  <h3 id="class-metadata-attributes">Class Metadata Attributes<a class="headerlink" href="#class-metadata-attributes" title="Permanent link">&para;</a></h3>
9912
- <p>Job-specific attributes may be defined under a class named <code>Meta</code> within each job class you implement. All of these are optional, but encouraged.</p>
10063
+ <p>Job-specific attributes may be defined under a class named <code>Meta</code> within each Job class you implement. All of these are optional, but encouraged.</p>
9913
10064
  <h4 id="name"><code>name</code><a class="headerlink" href="#name" title="Permanent link">&para;</a></h4>
9914
- <p>This is the human-friendly name of your job, as will be displayed in the Nautobot UI. If not set, the class name will be used.</p>
10065
+ <p>This is the human-friendly name of your Job, as will be displayed in the Nautobot UI. If not set, the class name will be used.</p>
9915
10066
  <div class="admonition note">
9916
10067
  <p class="admonition-title">Note</p>
9917
10068
  <p>In some UI elements and API endpoints, the class name is displayed in addition to or in place of this attribute, so even if defining this attribute, you should still choose an appropriately explanatory class name as well.</p>
9918
10069
  </div>
9919
10070
  <h4 id="description"><code>description</code><a class="headerlink" href="#description" title="Permanent link">&para;</a></h4>
9920
- <p>An optional human-friendly description of what this job does.
10071
+ <p>An optional human-friendly description of what this Job does.
9921
10072
  This can accept either plain text, Markdown-formatted text, or <a href="../../user-guide/platform-functionality/template-filters.html#render_markdown">a limited subset of HTML</a>. It can also be multiple lines:</p>
9922
10073
  <div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="k">class</span> <span class="nc">ExampleJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9923
10074
  <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
@@ -9929,63 +10080,79 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
9929
10080
  <a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="s2"> 3. It&#39;s a floor wax *and* a dessert topping</span>
9930
10081
  <a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a><span class="s2"> &quot;&quot;&quot;</span>
9931
10082
  </code></pre></div>
9932
- <p>If you code a multi-line description, the first line only will be used in the description column of the jobs list, while the full description will be rendered in the job detail view, submission, approval, and results pages.</p>
10083
+ <p>If you code a multi-line description, the first line only will be used in the description column of the Jobs list, while the full description will be rendered in the Job detail view, submission, approval, and results pages.</p>
9933
10084
  <h4 id="approval_required"><code>approval_required</code><a class="headerlink" href="#approval_required" title="Permanent link">&para;</a></h4>
9934
10085
  <p>Default: <code>False</code></p>
9935
- <p>A boolean that will mark this job as requiring approval from another user to be run. For more details on approvals, <a href="../../user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html">please refer to the section on scheduling and approvals</a>.</p>
10086
+ <p>A boolean that will mark this Job as requiring approval from another user to be run. For more details on approvals, <a href="../../user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html">please refer to the section on scheduling and approvals</a>.</p>
9936
10087
  <h4 id="dryrun_default"><code>dryrun_default</code><a class="headerlink" href="#dryrun_default" title="Permanent link">&para;</a></h4>
9937
10088
  <details class="version-changed">
9938
- <summary>Changed in version 2.0.0</summary>
9939
- <p>The <code>commit_default</code> field was renamed to <code>dryrun_default</code> and the default value was changed from <code>True</code> to <code>False</code>. The <code>commit</code> functionality that provided an automatic rollback of database changes if the job failed was removed. The <code>dryrun</code> functionality was added to provide a way to bypass job approval if a job implements a <a href="#dryrunvar"><code>DryRunVar</code></a>.</p>
10089
+ <summary>Changed in version 2.0.0 — Replacement for <code>commit_default</code></summary>
10090
+ <p>The <code>commit_default</code> field was renamed to <code>dryrun_default</code> and the default value was changed from <code>True</code> to <code>False</code>. The <code>commit</code> functionality that provided an automatic rollback of database changes if the Job failed was removed.</p>
9940
10091
  </details>
9941
10092
  <p>Default: <code>False</code></p>
9942
- <p>The checkbox to enable dryrun when executing a job is unchecked by default in the Nautobot UI. You can set <code>dryrun_default</code> to <code>True</code> under the <code>Meta</code> class if you want this option to instead be checked by default.</p>
10093
+ <p>If the Job implements a <a href="#dryrunvar"><code>DryRunVar</code></a>, what its default value should be.
10094
+ The checkbox to enable dryrun when executing a Job is unchecked by default in the Nautobot UI. You can set <code>dryrun_default</code> to <code>True</code> under the <code>Meta</code> class if you want this option to instead be checked by default.</p>
9943
10095
  <div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9944
10096
  <a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9945
10097
  <a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> <span class="n">dryrun_default</span> <span class="o">=</span> <span class="kc">True</span>
9946
10098
  </code></pre></div>
9947
10099
  <h4 id="field_order"><code>field_order</code><a class="headerlink" href="#field_order" title="Permanent link">&para;</a></h4>
9948
10100
  <p>Default: <code>[]</code></p>
9949
- <p>A list of strings (field names) representing the order your job <a href="#variables">variables</a> should be rendered as form fields in the job submission UI. If not defined, the variables will be listed in order of their definition in the code. If variables are defined on a parent class and no field order is defined, the parent class variables will appear before the subclass variables.</p>
10101
+ <p>A list of strings (field names) representing the order your Job <a href="#variables">variables</a> should be rendered as form fields in the Job submission UI. If not defined, the variables will be listed in order of their definition in the code. If variables are defined on a parent class and no field order is defined, the parent class variables will appear before the subclass variables.</p>
9950
10102
  <h4 id="has_sensitive_variables"><code>has_sensitive_variables</code><a class="headerlink" href="#has_sensitive_variables" title="Permanent link">&para;</a></h4>
9951
10103
  <details class="version-added">
9952
10104
  <summary>Added in version 1.3.10</summary>
9953
10105
  </details>
9954
10106
  <p>Default: <code>True</code></p>
9955
- <p>Unless set to False, it prevents the job's input parameters from being saved to the database. This defaults to True so as to protect against inadvertent database exposure of input parameters that may include sensitive data such as passwords or other user credentials. Review whether each job's inputs contain any such variables before setting this to False; if a job <em>does</em> contain sensitive inputs, if possible you should consider whether the job could be re-implemented using Nautobot's <a href="../../user-guide/platform-functionality/secret.html"><code>Secrets</code></a> feature as a way to ensure that the sensitive data is not directly provided as a job variable at all.</p>
9956
- <p>Important notes about jobs with sensitive variables:</p>
10107
+ <p>Unless set to False, it prevents the Job's input parameters from being saved to the database. This defaults to True so as to protect against inadvertent database exposure of input parameters that may include sensitive data such as passwords or other user credentials. Review whether each Job's inputs contain any such variables before setting this to False; if a Job <em>does</em> contain sensitive inputs, if possible you should consider whether the Job could be re-implemented using Nautobot's <a href="../../user-guide/platform-functionality/secret.html"><code>Secrets</code></a> feature as a way to ensure that the sensitive data is not directly provided as a Job variable at all.</p>
10108
+ <p>Important notes about Jobs with sensitive variables:</p>
9957
10109
  <ul>
9958
- <li>Such jobs cannot be scheduled to run in the future or on a recurring schedule (as scheduled jobs must by necessity store their variables in the database for future reference).</li>
9959
- <li>Jobs with sensitive variables cannot be marked as requiring approval (as jobs pending approval must store their variables in the database until approved).</li>
10110
+ <li>Such Jobs cannot be scheduled to run in the future or on a recurring schedule (as Scheduled Jobs must by necessity store their variables in the database for future reference).</li>
10111
+ <li>Jobs with sensitive variables cannot be marked as requiring approval (as Jobs pending approval must store their variables in the database until approved).</li>
9960
10112
  </ul>
9961
10113
  <h4 id="hidden"><code>hidden</code><a class="headerlink" href="#hidden" title="Permanent link">&para;</a></h4>
9962
10114
  <p>Default: <code>False</code></p>
9963
- <p>A Boolean that if set to <code>True</code> prevents the job from being displayed by default in the list of Jobs in the Nautobot UI.</p>
9964
- <p>Since the jobs execution framework is designed to be generic, there may be several technical jobs defined by users which interact with or are invoked by external systems. In such cases, these jobs are not meant to be executed by a human and likely do not make sense to expose to end users for execution, and thus having them exposed in the UI at all is extraneous.</p>
9965
- <p>Important notes about hidden jobs:</p>
10115
+ <p>A Boolean that if set to <code>True</code> prevents the Job from being displayed by default in the list of Jobs in the Nautobot UI.</p>
10116
+ <p>Since the Job execution framework is designed to be generic, there may be several technical Jobs defined by users which interact with or are invoked by external systems. In such cases, these Jobs are not meant to be executed by a human and likely do not make sense to expose to end users for execution, and thus having them exposed in the UI at all is extraneous.</p>
10117
+ <p>Important notes about hidden Jobs:</p>
9966
10118
  <ul>
9967
10119
  <li>This is merely hiding them by default from the web interface. It is NOT a security feature.</li>
9968
- <li>In the Jobs list view it is possible to filter to "Hidden: (no selection)" or even "Hidden: Yes" to list the hidden jobs.</li>
9969
- <li>All Job UI and REST API endpoints still exist for hidden jobs and can be accessed by any user who is aware of their existence.</li>
9970
- <li>Hidden jobs can still be executed through the UI or the REST API given the appropriate URL.</li>
9971
- <li>Results for hidden jobs will still appear in the Job Results list after they are run.</li>
10120
+ <li>In the Jobs list view it is possible to filter to "Hidden: (no selection)" or even "Hidden: Yes" to list the hidden Jobs.</li>
10121
+ <li>All Job UI and REST API endpoints still exist for hidden Jobs and can be accessed by any user who is aware of their existence.</li>
10122
+ <li>Hidden Jobs can still be executed through the UI or the REST API given the appropriate URL.</li>
10123
+ <li>Results for hidden Jobs will still appear in the Job Results list after they are run.</li>
10124
+ </ul>
10125
+ <h4 id="is_singleton"><code>is_singleton</code><a class="headerlink" href="#is_singleton" title="Permanent link">&para;</a></h4>
10126
+ <details class="version-added">
10127
+ <summary>Added in version 2.4.0</summary>
10128
+ </details>
10129
+ <p>Default: <code>False</code>
10130
+ A Boolean that if set to <code>True</code> prevents the job from running twice simultaneously.</p>
10131
+ <p>Any duplicate job instances will error out with a singleton-specific error message.</p>
10132
+ <p>Important notes about singleton jobs:</p>
10133
+ <ul>
10134
+ <li>The singleton functionality is implemented with a Redis key set to timeout either on the hard time out of the job or whenever the job terminates.<ul>
10135
+ <li>Therefore, a restart of Redis will wipe the singleton locks</li>
10136
+ </ul>
10137
+ </li>
10138
+ <li>A checkbox on the job run form makes it possible to force the singleton lock to be overridden. This makes it possible to recover from failure scenarios such as the original singleton job being stopped before it can unset the lock.</li>
9972
10139
  </ul>
9973
10140
  <h4 id="read_only"><code>read_only</code><a class="headerlink" href="#read_only" title="Permanent link">&para;</a></h4>
9974
10141
  <details class="version-added">
9975
10142
  <summary>Added in version 1.1.0</summary>
9976
10143
  </details>
9977
10144
  <details class="version-changed">
9978
- <summary>Changed in version 2.0.0</summary>
9979
- <p>The <code>read_only</code> flag no longer changes the behavior of Nautobot core and is up to the job author to decide whether their job should be considered read only.</p>
10145
+ <summary>Changed in version 2.0.0 — No automatic functionality</summary>
10146
+ <p>The <code>read_only</code> flag no longer changes the behavior of Nautobot core and is up to the Job author to decide whether their Job should be considered read only.</p>
9980
10147
  </details>
9981
10148
  <p>Default: <code>False</code></p>
9982
- <p>A boolean that can be set by the job author to indicate that the job does not make any changes to the environment. What behavior makes each job "read only" is up to the individual job author to decide. Note that user input may still be optionally collected with read-only jobs via job variables, as described below.</p>
10149
+ <p>A boolean that can be set by the Job author to indicate that the Job does not make any changes to the environment. What behavior makes each Job "read only" is up to the individual Job author to decide. Note that user input may still be optionally collected with read-only Jobs via Job variables, as described below.</p>
9983
10150
  <h4 id="soft_time_limit"><code>soft_time_limit</code><a class="headerlink" href="#soft_time_limit" title="Permanent link">&para;</a></h4>
9984
10151
  <details class="version-added">
9985
10152
  <summary>Added in version 1.3.0</summary>
9986
10153
  </details>
9987
- <p>An int or float value, in seconds, which can be used to override the default <a href="../../user-guide/administration/configuration/settings.html#celery_task_soft_time_limit">soft time limit</a> for a job task to complete.</p>
9988
- <p>The <code>celery.exceptions.SoftTimeLimitExceeded</code> exception will be raised when this soft time limit is exceeded. The job task can catch this to clean up before the <a href="../../user-guide/administration/configuration/settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) is reached:</p>
10154
+ <p>An int or float value, in seconds, which can be used to override the default <a href="../../user-guide/administration/configuration/settings.html#celery_task_soft_time_limit">soft time limit</a> for a Job task to complete.</p>
10155
+ <p>The <code>celery.exceptions.SoftTimeLimitExceeded</code> exception will be raised when this soft time limit is exceeded. The Job task can catch this to clean up before the <a href="../../user-guide/administration/configuration/settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) is reached:</p>
9989
10156
  <div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="kn">from</span> <span class="nn">celery.exceptions</span> <span class="kn">import</span> <span class="n">SoftTimeLimitExceeded</span>
9990
10157
  <a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9991
10158
  <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>
@@ -10008,20 +10175,20 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
10008
10175
  <summary>Added in version 1.5.0</summary>
10009
10176
  </details>
10010
10177
  <p>Default: <code>[]</code></p>
10011
- <p>A list of Job Queue names that the job can be routed to. An empty list will default to only allowing the user to select the <a href="../../user-guide/administration/configuration/settings.html#celery_task_default_queue">default Celery queue</a> (<code>default</code> unless changed by an administrator). The queue specified in the job's <code>default_job_queue</code> will be used if a queue is not specified in a job run API call.</p>
10178
+ <p>A list of Job Queue names that the Job can be routed to. An empty list will default to only allowing the user to select the <a href="../../user-guide/administration/configuration/settings.html#celery_task_default_queue">default Celery queue</a> (<code>default</code> unless changed by an administrator). The queue specified in the Job's <code>default_job_queue</code> will be used if a queue is not specified in a Job run API call.</p>
10012
10179
  <details class="version-changed">
10013
10180
  <summary>Changed in version 2.4.0 — Changed default queue selection</summary>
10014
10181
  <p>As a result of the addition of Job Queues, the default queue when running a Job without explicitly selecting a queue is now the job queue specified in the <code>default_job_queue</code> field on the Job model. <code>default_job_queue</code> fields for any existing Job instances are automatically populated with the name of the first entry in <code>task_queues</code> list of the Job class. When <code>task_queues</code> list on the Job class is empty, the corresponding Job instance's <code>default_job_queue</code> will be the job queue with the name provided by <code>settings.CELERY_TASK_DEFAULT_QUEUE</code>. You can also override the initial <code>default_job_queue</code> by setting <code>default_job_queue_override</code> to True and assign the field with a different Job Queue instance.</p>
10015
10182
  </details>
10016
10183
  <div class="admonition note">
10017
10184
  <p class="admonition-title">Note</p>
10018
- <p>A worker must be listening on the requested queue or the job will not run. See the documentation on <a href="../../user-guide/administration/guides/celery-queues.html">task queues</a> for more information.</p>
10185
+ <p>A worker must be listening on the requested queue or the Job will not run. See the documentation on <a href="../../user-guide/administration/guides/celery-queues.html">task queues</a> for more information.</p>
10019
10186
  </div>
10020
10187
  <h4 id="template_name"><code>template_name</code><a class="headerlink" href="#template_name" title="Permanent link">&para;</a></h4>
10021
10188
  <details class="version-added">
10022
10189
  <summary>Added in version 1.4.0</summary>
10023
10190
  </details>
10024
- <p>A path relative to the job source code containing a Django template which provides additional code to customize the Job's submission form. This template should extend the existing job template, <code>extras/job.html</code>, otherwise the base form and functionality may not be available.</p>
10191
+ <p>A path relative to the Job source code containing a Django template which provides additional code to customize the Job's submission form. This template should extend the existing Job template, <code>extras/job.html</code>, otherwise the base form and functionality may not be available.</p>
10025
10192
  <p>A template can provide additional JavaScript, CSS, or even display HTML. A good starting template would be:</p>
10026
10193
  <div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>{% extends &#39;extras/job.html&#39; %}
10027
10194
  <a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>
@@ -10039,7 +10206,7 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
10039
10206
  <a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a>{% endblock javascript %}
10040
10207
  </code></pre></div>
10041
10208
  <details class="version-added">
10042
- <summary>Added in version 2.2.0</summary>
10209
+ <summary>Added in version 2.2.0 — Additional blocks</summary>
10043
10210
  <p>Added the <code>job_form</code> and <code>schedule_form</code> sub-blocks to <code>extras/job.html</code>, for use by Jobs that just want to override the rendered forms without replacing all of <code>{% block content %}</code>.</p>
10044
10211
  </details>
10045
10212
  <p>For another example checkout <a href="https://github.com/nautobot/nautobot/blob/main/examples/example_app/example_app/templates/example_app/example_with_custom_template.html">the template used in the Example App</a> in the GitHub repo.</p>
@@ -10048,7 +10215,7 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
10048
10215
  <summary>Added in version 1.3.0</summary>
10049
10216
  </details>
10050
10217
  <p>An int or float value, in seconds, which can be used to override the
10051
- default <a href="../../user-guide/administration/configuration/settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) for a job task to complete.</p>
10218
+ default <a href="../../user-guide/administration/configuration/settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) for a Job task to complete.</p>
10052
10219
  <p>Unlike the <code>soft_time_limit</code> above, no exceptions are raised when a <code>time_limit</code> is exceeded. The task will just terminate silently:</p>
10053
10220
  <div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
10054
10221
  <a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>
@@ -10064,11 +10231,11 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
10064
10231
  <a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a> <span class="n">job_code</span><span class="p">()</span>
10065
10232
  </code></pre></div>
10066
10233
  <div class="admonition note">
10067
- <p class="admonition-title">Note</p>
10068
- <p>If the <code>time_limit</code> is set to a value less than or equal to the <code>soft_time_limit</code>, a warning log is generated to inform the user that this job will fail silently after the <code>time_limit</code> as the <code>soft_time_limit</code> will never be reached.</p>
10234
+ <p class="admonition-title"><code>time_limit</code> versus <code>soft_time_limit</code></p>
10235
+ <p>If the <code>time_limit</code> is set to a value less than or equal to the <code>soft_time_limit</code>, a warning log is generated to inform the user that this Job will fail silently after the <code>time_limit</code> as the <code>soft_time_limit</code> will never be reached.</p>
10069
10236
  </div>
10070
10237
  <h3 id="variables">Variables<a class="headerlink" href="#variables" title="Permanent link">&para;</a></h3>
10071
- <p>Variables allow your job to accept user input via the Nautobot UI, but they are optional; if your job does not require any user input, there is no need to define any variables. Conversely, if you are making use of user input in your job, you <em>must</em> also implement the <code>run()</code> method, as it is the only entry point to your job that has visibility into the variable values provided by the user.</p>
10238
+ <p>Variables allow your Job to accept user input via the Nautobot UI, but they are optional; if your Job does not require any user input, there is no need to define any variables. Conversely, if you are making use of user input in your Job, you <em>must</em> also implement the <code>run()</code> method, as it is the only entry point to your Job that has visibility into the variable values provided by the user.</p>
10072
10239
  <div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
10073
10240
  <a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>
10074
10241
  <a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
@@ -10081,7 +10248,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
10081
10248
  </code></pre></div>
10082
10249
  <p>The remainder of this section documents the various supported variable types and how to make use of them.</p>
10083
10250
  <h4 id="default-variable-options">Default Variable Options<a class="headerlink" href="#default-variable-options" title="Permanent link">&para;</a></h4>
10084
- <p>All job variables support the following default options:</p>
10251
+ <p>All Job variables support the following default options:</p>
10085
10252
  <ul>
10086
10253
  <li><code>default</code> - The field's default value</li>
10087
10254
  <li><code>description</code> - A brief user-friendly description of the field</li>
@@ -10103,7 +10270,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
10103
10270
  <details class="version-added">
10104
10271
  <summary>Added in version 2.1.0</summary>
10105
10272
  </details>
10106
- <p>Accepts JSON-formatted data of any length. Renders as a multi-line text input field. The variable passed to <code>run()</code> method on the job has been serialized to the appropriate Python objects.</p>
10273
+ <p>Accepts JSON-formatted data of any length. Renders as a multi-line text input field. The variable passed to <code>run()</code> method on the Job has been serialized to the appropriate Python objects.</p>
10107
10274
  <div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="k">class</span> <span class="nc">ExampleJSONVarJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
10108
10275
  <a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a> <span class="n">var1</span> <span class="o">=</span> <span class="n">JSONVar</span><span class="p">()</span>
10109
10276
  <a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
@@ -10111,7 +10278,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
10111
10278
  <a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a> <span class="c1"># var1 form data equals &#39;{&quot;key1&quot;: &quot;value1&quot;}&#39;</span>
10112
10279
  <a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;The value of key1 is: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">var1</span><span class="p">[</span><span class="s2">&quot;key1&quot;</span><span class="p">])</span>
10113
10280
  </code></pre></div>
10114
- <p>In the above example <code>{"key1": "value1"}</code> is provided to the job form, on submission first the field is validated to be JSON-formatted data then is serialized and passed to the <code>run()</code> method as a dictionary without any need for the job developer to post-process the variable into a Python dictionary.</p>
10281
+ <p>In the above example <code>{"key1": "value1"}</code> is provided to the Job form, on submission first the field is validated to be JSON-formatted data then is serialized and passed to the <code>run()</code> method as a dictionary without any need for the Job developer to post-process the variable into a Python dictionary.</p>
10115
10282
  <h4 id="integervar"><code>IntegerVar</code><a class="headerlink" href="#integervar" title="Permanent link">&para;</a></h4>
10116
10283
  <p>Stores a numeric integer. Options include:</p>
10117
10284
  <ul>
@@ -10121,7 +10288,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
10121
10288
  <h4 id="booleanvar"><code>BooleanVar</code><a class="headerlink" href="#booleanvar" title="Permanent link">&para;</a></h4>
10122
10289
  <p>A true/false flag. This field has no options beyond the defaults listed above.</p>
10123
10290
  <h4 id="dryrunvar"><code>DryRunVar</code><a class="headerlink" href="#dryrunvar" title="Permanent link">&para;</a></h4>
10124
- <p>A true/false flag with special handling for jobs that require approval. If <code>dryrun = DryRunVar()</code> is declared on a job class, approval may be bypassed if <code>dryrun</code> is set to <code>True</code> on job execution.</p>
10291
+ <p>A true/false flag with special handling for Jobs that require approval. If <code>dryrun = DryRunVar()</code> is declared on a Job class, approval may be bypassed if <code>dryrun</code> is set to <code>True</code> on Job execution.</p>
10125
10292
  <h4 id="choicevar"><code>ChoiceVar</code><a class="headerlink" href="#choicevar" title="Permanent link">&para;</a></h4>
10126
10293
  <p>A set of choices from which the user can select one.</p>
10127
10294
  <ul>
@@ -10198,7 +10365,7 @@ Another example of using the nested reference would be to access <a href="../../
10198
10365
  <h4 id="multiobjectvar"><code>MultiObjectVar</code><a class="headerlink" href="#multiobjectvar" title="Permanent link">&para;</a></h4>
10199
10366
  <p>Similar to <code>ObjectVar</code>, but allows for the selection of multiple objects.</p>
10200
10367
  <h4 id="filevar"><code>FileVar</code><a class="headerlink" href="#filevar" title="Permanent link">&para;</a></h4>
10201
- <p>An uploaded file. Note that uploaded files are present in memory only for the duration of the job's execution: They will not be automatically saved for future use. The job is responsible for writing file contents to disk where necessary.</p>
10368
+ <p>An uploaded file. Note that uploaded files are present in memory only for the duration of the Job's execution: They will not be automatically saved for future use. The Job is responsible for writing file contents to disk where necessary.</p>
10202
10369
  <h4 id="ipaddressvar"><code>IPAddressVar</code><a class="headerlink" href="#ipaddressvar" title="Permanent link">&para;</a></h4>
10203
10370
  <p>An IPv4 or IPv6 address, without a mask. Returns a <code>netaddr.IPAddress</code> object.</p>
10204
10371
  <h4 id="ipaddresswithmaskvar"><code>IPAddressWithMaskVar</code><a class="headerlink" href="#ipaddresswithmaskvar" title="Permanent link">&para;</a></h4>
@@ -10213,14 +10380,14 @@ Another example of using the nested reference would be to access <a href="../../
10213
10380
  <p>Nautobot Jobs when executed will be instantiated by Nautobot, then Nautobot will call in order the special API methods <code>before_start()</code>, <code>run()</code>, <code>on_success()</code>/<code>on_failure()</code>, and <code>after_return()</code>. You must implement the <code>run()</code> method; the other methods have default implementations that do nothing.</p>
10214
10381
  <p>As Jobs are Python classes, you are of course free to define any number of other helper methods or functions that you call yourself from within any of the above special methods, but the above are the only ones that will be automatically called.</p>
10215
10382
  <details class="version-removed">
10216
- <summary>Removed in version 2.0.0</summary>
10383
+ <summary>Removed in version 2.0.0 — Removal of <code>test</code> and <code>post_run</code> special methods</summary>
10217
10384
  <p>The NetBox backwards compatible <code>test_*()</code> and <code>post_run()</code> special methods have been removed.</p>
10218
10385
  </details>
10219
10386
  <h4 id="the-before_start-method">The <code>before_start()</code> Method<a class="headerlink" href="#the-before_start-method" title="Permanent link">&para;</a></h4>
10220
10387
  <p>The <code>before_start()</code> method may optionally be implemented to perform any appropriate Job-specific setup before the <code>run()</code> method is called. It has the signature <code>before_start(self, task_id, args, kwargs)</code> for historical reasons; the <code>task_id</code> parameter will always be identical to <code>self.request.id</code>, the <code>args</code> parameter will generally be empty, and any user-specified variables passed into the Job execution will be present in the <code>kwargs</code> parameter.</p>
10221
10388
  <p>The return value from <code>before_start()</code> is ignored, but if it raises any exception, the Job execution will be marked as a failure and <code>run()</code> will not be called.</p>
10222
10389
  <h4 id="the-run-method">The <code>run()</code> Method<a class="headerlink" href="#the-run-method" title="Permanent link">&para;</a></h4>
10223
- <p>The <code>run()</code> method is the primary worker of any Job, and must be implemented. After the <code>self</code> argument, it should accept keyword arguments for any variables defined on the job:</p>
10390
+ <p>The <code>run()</code> method is the primary worker of any Job, and must be implemented. After the <code>self</code> argument, it should accept keyword arguments for any variables defined on the Job:</p>
10224
10391
  <div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
10225
10392
  <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>
10226
10393
  <a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
@@ -10231,13 +10398,13 @@ Another example of using the nested reference would be to access <a href="../../
10231
10398
  <a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
10232
10399
  <a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="o">...</span>
10233
10400
  </code></pre></div>
10234
- <p>Again, defining user variables is totally optional; you may create a job with a <code>run()</code> method with only the <code>self</code> argument if no user input is needed.</p>
10401
+ <p>Again, defining user variables is totally optional; you may create a Job with a <code>run()</code> method with only the <code>self</code> argument if no user input is needed.</p>
10235
10402
  <div class="admonition warning">
10236
- <p class="admonition-title">Warning</p>
10403
+ <p class="admonition-title">Use <code>validated_save()</code> where applicable</p>
10237
10404
  <p>When writing Jobs that create and manipulate data it is recommended to make use of the <code>validated_save()</code> convenience method which exists on all core models. This method saves the instance data but first enforces model validation logic. Simply calling <code>save()</code> on the model instance <strong>does not</strong> enforce validation automatically and may lead to bad data. See the development <a href="../core/best-practices.html">best practices</a>.</p>
10238
10405
  </div>
10239
10406
  <div class="admonition warning">
10240
- <p class="admonition-title">Warning</p>
10407
+ <p class="admonition-title">Be cautious around bulk operations</p>
10241
10408
  <p>The Django ORM provides methods to create/edit many objects at once, namely <code>bulk_create()</code> and <code>update()</code>. These are best avoided in most cases as they bypass a model's built-in validation and can easily lead to database corruption if not used carefully.</p>
10242
10409
  </div>
10243
10410
  <p>If <code>run()</code> returns any value (even the implicit <code>None</code>), the Job execution will be marked as a success and the returned value will be stored in the associated JobResult database record. Conversely, if <code>run()</code> raises any exception, the Job execution will be marked as a failure and the traceback will be stored in the JobResult.</p>
@@ -10251,8 +10418,8 @@ Another example of using the nested reference would be to access <a href="../../
10251
10418
  <details class="version-changed">
10252
10419
  <summary>Changed in version 2.0.0</summary>
10253
10420
  </details>
10254
- <p>Messages logged from a job's logger will be stored in <a href="../../user-guide/platform-functionality/jobs/models.html#job-log-entry"><code>JobLogEntry</code></a> records associated with the current <a href="../../user-guide/platform-functionality/jobs/models.html#job-results"><code>JobResult</code></a>.</p>
10255
- <p>The logger can be accessed either by using the <code>logger</code> property on the job class or <code>nautobot.extras.jobs.get_task_logger(__name__)</code>. Both will return the same logger instance. For more information on the standard Python logging module, see the <a href="https://docs.python.org/3/library/logging.html">Python documentation</a>.</p>
10421
+ <p>Messages logged from a Job's logger will be stored in <a href="../../user-guide/platform-functionality/jobs/models.html#job-log-entry"><code>JobLogEntry</code></a> records associated with the current <a href="../../user-guide/platform-functionality/jobs/models.html#job-results"><code>JobResult</code></a>.</p>
10422
+ <p>The logger can be accessed either by using the <code>logger</code> property on the Job class or <code>nautobot.extras.jobs.get_task_logger(__name__)</code>. Both will return the same logger instance. For more information on the standard Python logging module, see the <a href="https://docs.python.org/3/library/logging.html">Python documentation</a>.</p>
10256
10423
  <p>The logger accepts an <code>extra</code> kwarg that you can optionally set for the following features:</p>
10257
10424
  <ul>
10258
10425
  <li><code>grouping</code>- Replaces the <code>active_test</code> Job property in Nautobot v1.X</li>
@@ -10281,16 +10448,16 @@ Another example of using the nested reference would be to access <a href="../../
10281
10448
  </div>
10282
10449
  <p>Markdown rendering is supported for log messages, as well as <a href="../../user-guide/platform-functionality/template-filters.html#render_markdown">a limited subset of HTML</a>.</p>
10283
10450
  <details class="version-changed">
10284
- <summary>Changed in version 1.3.4</summary>
10285
- <p>As a security measure, the <code>message</code> passed to any of these methods will be passed through the <code>nautobot.core.utils.logging.sanitize()</code> function in an attempt to strip out information such as usernames/passwords that should not be saved to the logs. This is of course best-effort only, and Job authors should take pains to ensure that such information is not passed to the logging APIs in the first place. The set of redaction rules used by the <code>sanitize()</code> function can be configured as <a href="../../user-guide/administration/configuration/settings.html#sanitizer_patterns">settings.SANITIZER_PATTERNS</a>.</p>
10451
+ <summary>Changed in version 1.3.4 — Log entry sanitization</summary>
10452
+ <p>As a security measure, the <code>message</code> passed to any of these methods will be passed through the <code>nautobot.core.utils.logging.sanitize()</code> function in an attempt to strip out information such as usernames/passwords that should not be saved to the logs. This is of course best-effort only, and Job authors should take pains to ensure that such information is not passed to the logging APIs in the first place. The set of redaction rules used by the <code>sanitize()</code> function can be configured as <a href="../../user-guide/administration/configuration/settings.html#sanitizer_patterns"><code>settings.SANITIZER_PATTERNS</code></a>.</p>
10286
10453
  </details>
10287
10454
  <details class="version-changed">
10288
- <summary>Changed in version 2.0.0</summary>
10289
- <p>The Job class logging functions (example: <code>self.log(message)</code>, <code>self.log_success(obj=None, message=message)</code>, etc) have been removed. Also, the convenience method to mark a job as failed, <code>log_failure()</code>, has been removed. To replace the functionality of this method, you can log an error message with <code>self.logger.error()</code> and then raise an exception to fail the job. Note that it is no longer possible to manually set the job result status as failed without raising an exception in the job.</p>
10455
+ <summary>Changed in version 2.0.0 — Significant API changes</summary>
10456
+ <p>The Job class logging functions (example: <code>self.log(message)</code>, <code>self.log_success(obj=None, message=message)</code>, etc) have been removed. Also, the convenience method to mark a Job as failed, <code>log_failure()</code>, has been removed. To replace the functionality of this method, you can log an error message with <code>self.logger.error()</code> and then raise an exception to fail the Job. Note that it is no longer possible to manually set the Job Result status as failed without raising an exception in the Job.</p>
10290
10457
  </details>
10291
10458
  <details class="version-changed">
10292
10459
  <summary>Changed in version 2.0.0</summary>
10293
- <p>The <code>AbortTransaction</code> class was moved from the <code>nautobot.utilities.exceptions</code> module to <code>nautobot.core.exceptions</code>.</p>
10460
+ <p>The <code>AbortTransaction</code> class was moved from the <code>nautobot.utilities.exceptions</code> module to <code>nautobot.core.exceptions</code>. Jobs should generally import it from <code>nautobot.apps.exceptions</code> if needed.</p>
10294
10461
  </details>
10295
10462
  <details class="version-added">
10296
10463
  <summary>Added in version 2.4.0</summary>
@@ -10311,8 +10478,8 @@ Another example of using the nested reference would be to access <a href="../../
10311
10478
  <p>The above Job when run will create two files, "greeting.txt" and "farewell.txt", that will be made available for download from the JobResult detail view's "Advanced" tab and via the REST API. These files will persist indefinitely, but can automatically be deleted if the JobResult itself is deleted; they can also be deleted manually by an administrator via the "File Proxies" link in the Admin UI.</p>
10312
10479
  <p>The maximum size of any single created file (or in other words, the maximum number of bytes that can be passed to <code>self.create_file()</code>) is controlled by the <a href="../../user-guide/administration/configuration/settings.html#job_create_file_max_size"><code>JOB_CREATE_FILE_MAX_SIZE</code></a> system setting. A <code>ValueError</code> exception will be raised if <code>create_file()</code> is called with an overly large <code>content</code> value.</p>
10313
10480
  <h3 id="marking-a-job-as-failed">Marking a Job as Failed<a class="headerlink" href="#marking-a-job-as-failed" title="Permanent link">&para;</a></h3>
10314
- <p>To mark a job as failed, raise an exception from within the <code>run()</code> method. The exception message will be logged to the traceback of the job result. The job result status will be set to <code>failed</code>. To output a job log message you can use the <code>self.logger.error()</code> method.</p>
10315
- <p>As an example, the following job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
10481
+ <p>To mark a Job as failed, raise an exception from within the <code>run()</code> method. The exception message will be logged to the traceback of the Job Result. The Job Result status will be set to <code>failed</code>. To output a Job log message you can use the <code>self.logger.error()</code> method.</p>
10482
+ <p>As an example, the following Job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
10316
10483
  <div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span>
10317
10484
  <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>
10318
10485
  <a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
@@ -10325,10 +10492,10 @@ Another example of using the nested reference would be to access <a href="../../
10325
10492
  </code></pre></div>
10326
10493
  <h3 id="accessing-user-and-job-result">Accessing User and Job Result<a class="headerlink" href="#accessing-user-and-job-result" title="Permanent link">&para;</a></h3>
10327
10494
  <details class="version-changed">
10328
- <summary>Changed in version 2.0.0</summary>
10495
+ <summary>Changed in version 2.0.0 — Significant API change</summary>
10329
10496
  <p>The <code>request</code> property has been changed to a Celery request instead of a Django web request and no longer includes the information from the web request that initiated the Job. The <code>user</code> object is now available as <code>self.user</code> instead of <code>self.request.user</code>.</p>
10330
10497
  </details>
10331
- <p>The user that initiated the job and the job result associated to the job can be accessed through properties on the job class:</p>
10498
+ <p>The user that initiated the Job and the Job Result associated to the Job can be accessed through properties on the Job class:</p>
10332
10499
  <div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="n">username</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">username</span>
10333
10500
  <a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="n">job_result_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">job_result</span><span class="o">.</span><span class="n">id</span>
10334
10501
  <a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Job </span><span class="si">%s</span><span class="s2"> initiated by user </span><span class="si">%s</span><span class="s2"> is running.&quot;</span><span class="p">,</span> <span class="n">job_result_id</span><span class="p">,</span> <span class="n">username</span><span class="p">)</span>
@@ -10350,7 +10517,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10350
10517
  </details>
10351
10518
  <p>The simplest way to test the entire execution of Jobs is via calling the <code>nautobot.apps.testing.run_job_for_testing()</code> method, which is a helper wrapper around the <code>JobResult.enqueue_job</code> function used to execute a Job via Nautobot's Celery worker process.</p>
10352
10519
  <p>Because of the way <code>run_job_for_testing</code> and more specifically Celery tasks work, which is somewhat complex behind the scenes, you need to inherit from <code>nautobot.apps.testing.TransactionTestCase</code> instead of <code>django.test.TestCase</code> (Refer to the <a href="https://docs.djangoproject.com/en/stable/topics/testing/tools/#provided-test-case-classes">Django documentation</a> if you're interested in the differences between these classes - <code>TransactionTestCase</code> from Nautobot is a small wrapper around Django's <code>TransactionTestCase</code>).</p>
10353
- <p>When using <code>TransactionTestCase</code> (whether from Django or from Nautobot) each tests runs on a completely empty database. Furthermore, Nautobot requires new jobs to be enabled before they can run. Therefore, we need to make sure the job is enabled before each run which <code>run_job_for_testing</code> handles for us.</p>
10520
+ <p>When using <code>TransactionTestCase</code> (whether from Django or from Nautobot) each tests runs on a completely empty database. Furthermore, Nautobot requires new Jobs to be enabled before they can run. Therefore, we need to make sure the Job is enabled before each run which <code>run_job_for_testing</code> handles for us.</p>
10354
10521
  <p>A simple example of a Job test case might look like the following:</p>
10355
10522
  <div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.testing</span> <span class="kn">import</span> <span class="n">run_job_for_testing</span><span class="p">,</span> <span class="n">TransactionTestCase</span>
10356
10523
  <a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">JobLogEntry</span>
@@ -10372,15 +10539,15 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10372
10539
  <p class="admonition-title">Tip</p>
10373
10540
  <p>For more advanced examples refer to the Nautobot source code, specifically <code>nautobot/extras/tests/test_jobs.py</code>.</p>
10374
10541
  </div>
10375
- <h2 id="debugging-job-performance">Debugging job performance<a class="headerlink" href="#debugging-job-performance" title="Permanent link">&para;</a></h2>
10542
+ <h2 id="debugging-job-performance">Debugging Job Performance<a class="headerlink" href="#debugging-job-performance" title="Permanent link">&para;</a></h2>
10376
10543
  <details class="version-added">
10377
10544
  <summary>Added in version 1.5.17</summary>
10378
10545
  </details>
10379
- <p>Debugging the performance of Nautobot jobs can be tricky, because they are executed in the worker context. In order to gain extra visibility, <a href="https://docs.python.org/3/library/profile.html">cProfile</a> can be used to profile the job execution.</p>
10380
- <p>The 'profile' form field on jobs is automatically available when the <code>DEBUG</code> settings is <code>True</code>. When you select that checkbox, a profiling report in the pstats format will be written to the file system of the environment where the job runs. Normally, this is on the file system of the worker process, but if you are using the <code>nautobot-server runjob</code> command with <code>--local</code>, it will end up in the file system of the web application itself. The path of the written file will be logged in the job.</p>
10546
+ <p>Debugging the performance of Nautobot Jobs can be tricky, because they are executed in the worker context. In order to gain extra visibility, <a href="https://docs.python.org/3/library/profile.html">cProfile</a> can be used to profile the Job execution.</p>
10547
+ <p>The 'profile' form field on Jobs is automatically available when the <code>DEBUG</code> settings is <code>True</code>. When you select that checkbox, a profiling report in the pstats format will be written to the file system of the environment where the Job runs. Normally, this is on the file system of the worker process, but if you are using the <code>nautobot-server runjob</code> command with <code>--local</code>, it will end up in the file system of the web application itself. The path of the written file will be logged in the Job.</p>
10381
10548
  <div class="admonition note">
10382
10549
  <p class="admonition-title">Note</p>
10383
- <p>If you need to run this in an environment where <code>DEBUG</code> is <code>False</code>, you have the option of using <code>nautobot-server runjob</code> with the <code>--profile</code> flag. According to the docs, <code>cProfile</code> should have minimal impact on the performance of the job; still, proceed with caution when using this in a production environment.</p>
10550
+ <p>If you need to run this in an environment where <code>DEBUG</code> is <code>False</code>, you have the option of using <code>nautobot-server runjob</code> with the <code>--profile</code> flag. According to the docs, <code>cProfile</code> should have minimal impact on the performance of the Job; still, proceed with caution when using this in a production environment.</p>
10384
10551
  </div>
10385
10552
  <h3 id="reading-profiling-reports">Reading profiling reports<a class="headerlink" href="#reading-profiling-reports" title="Permanent link">&para;</a></h3>
10386
10553
  <p>A full description on how to deal with the output of <code>cProfile</code> can be found in the <a href="https://docs.python.org/3/library/profile.html#instant-user-s-manual">Instant User's Manual</a>, but here is something to get you started:</p>
@@ -10389,16 +10556,18 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10389
10556
  <a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="n">stats</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;/tmp/nautobot-jobresult-</span><span class="si">{</span><span class="n">job_result_uuid</span><span class="si">}</span><span class="s2">.pstats&quot;</span><span class="p">)</span>
10390
10557
  <a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="n">stats</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">pstats</span><span class="o">.</span><span class="n">SortKey</span><span class="o">.</span><span class="n">CUMULATIVE</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
10391
10558
  </code></pre></div>
10392
- <p>This will print the 10 functions that the job execution spent the most time in - adapt this to your needs!</p>
10559
+ <p>This will print the 10 functions that the Job execution spent the most time in - adapt this to your needs!</p>
10393
10560
  <h2 id="example-jobs">Example Jobs<a class="headerlink" href="#example-jobs" title="Permanent link">&para;</a></h2>
10561
+ <h3 id="example-everything-job">Example "Everything" Job<a class="headerlink" href="#example-everything-job" title="Permanent link">&para;</a></h3>
10562
+ <p>The "Example App" included with the Nautobot source code <a href="https://github.com/nautobot/nautobot/blob/main/examples/example_app/example_app/jobs.py">includes a number of simple sample Jobs</a>, including an <code>ExampleEverythingJob</code> class that demonstrates and documents the usage of the various metadata attributes, input variable types, and magic methods that a Job can support. As Job functionality will continue to evolve over time, if using this file as a reference, please make sure that you're viewing the version of this Job that corresponds to your target Nautobot version.</p>
10394
10563
  <h3 id="creating-objects-for-a-planned-location">Creating objects for a planned location<a class="headerlink" href="#creating-objects-for-a-planned-location" title="Permanent link">&para;</a></h3>
10395
- <p>This job prompts the user for three variables:</p>
10564
+ <p>This Job prompts the user for three variables:</p>
10396
10565
  <ul>
10397
10566
  <li>The name of the new location</li>
10398
10567
  <li>The device model (a filtered list of defined device types)</li>
10399
10568
  <li>The number of access switches to create</li>
10400
10569
  </ul>
10401
- <p>These variables are presented as a web form to be completed by the user. Once submitted, the job's <code>run()</code> method is called to create the appropriate objects, and it returns simple CSV output to the user summarizing the created objects.</p>
10570
+ <p>These variables are presented as a web form to be completed by the user. Once submitted, the Job's <code>run()</code> method is called to create the appropriate objects, and it returns simple CSV output to the user summarizing the created objects.</p>
10402
10571
  <div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span>
10403
10572
  <a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>
10404
10573
  <a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span><span class="p">,</span> <span class="n">register_jobs</span>
@@ -10458,7 +10627,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10458
10627
  <a id="__codelineno-26-57" name="__codelineno-26-57" href="#__codelineno-26-57"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">NewBranch</span><span class="p">)</span>
10459
10628
  </code></pre></div>
10460
10629
  <h3 id="device-validation">Device validation<a class="headerlink" href="#device-validation" title="Permanent link">&para;</a></h3>
10461
- <p>A job to perform various validation of Device data in Nautobot. As this job does not require any user input, it does not define any variables.</p>
10630
+ <p>A Job to perform various validation of Device data in Nautobot. As this Job does not require any user input, it does not define any variables.</p>
10462
10631
  <div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
10463
10632
  <a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">ConsolePort</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">PowerPort</span>
10464
10633
  <a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
@@ -10511,9 +10680,9 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10511
10680
  <a id="__codelineno-27-50" name="__codelineno-27-50" href="#__codelineno-27-50"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">DeviceConnectionsReport</span><span class="p">)</span>
10512
10681
  </code></pre></div>
10513
10682
  <h2 id="job-button-receivers">Job Button Receivers<a class="headerlink" href="#job-button-receivers" title="Permanent link">&para;</a></h2>
10514
- <p>Job Buttons are only able to initiate a specific type of job called a <strong>Job Button Receiver</strong>. These are jobs that subclass the <code>nautobot.apps.jobs.JobButtonReceiver</code> class. Job Button Receivers are similar to normal jobs except they are hard coded to accept only <code>object_pk</code> and <code>object_model_name</code> <a href="#variables">variables</a>. Job Button Receivers are hidden from the jobs listing UI by default but otherwise function similarly to other jobs. The <code>JobButtonReceiver</code> class only implements one method called <code>receive_job_button</code>.</p>
10683
+ <p>Job Buttons are only able to initiate a specific type of Job called a <strong>Job Button Receiver</strong>. These are Jobs that subclass the <code>nautobot.apps.jobs.JobButtonReceiver</code> class. Job Button Receivers are similar to normal Jobs except they are hard coded to accept only <code>object_pk</code> and <code>object_model_name</code> <a href="#variables">variables</a>. The <code>JobButtonReceiver</code> class only implements one method called <code>receive_job_button</code>.</p>
10515
10684
  <div class="admonition note">
10516
- <p class="admonition-title">Note</p>
10685
+ <p class="admonition-title">Disabled by default just like other Jobs</p>
10517
10686
  <p>Job Button Receivers still need to be <a href="../../user-guide/platform-functionality/jobs/index.html#enabling-jobs-for-running">enabled through the web UI</a> before they can be used just like other Jobs.</p>
10518
10687
  </div>
10519
10688
  <h3 id="the-receive_job_button-method">The <code>receive_job_button()</code> Method<a class="headerlink" href="#the-receive_job_button-method" title="Permanent link">&para;</a></h3>
@@ -10576,14 +10745,14 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10576
10745
  <a id="__codelineno-29-36" name="__codelineno-29-36" href="#__codelineno-29-36"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleComplexJobButtonReceiver</span><span class="p">)</span>
10577
10746
  </code></pre></div>
10578
10747
  <h2 id="job-hook-receivers">Job Hook Receivers<a class="headerlink" href="#job-hook-receivers" title="Permanent link">&para;</a></h2>
10579
- <p>Job Hooks are only able to initiate a specific type of job called a <strong>Job Hook Receiver</strong>. These are jobs that subclass the <code>nautobot.apps.jobs.JobHookReceiver</code> class. Job hook receivers are similar to normal jobs except they are hard coded to accept only an <code>object_change</code> <a href="#variables">variable</a>. Job Hook Receivers are hidden from the jobs listing UI by default but otherwise function similarly to other jobs. The <code>JobHookReceiver</code> class only implements one method called <code>receive_job_hook</code>.</p>
10748
+ <p>Job Hooks are only able to initiate a specific type of Job called a <strong>Job Hook Receiver</strong>. These are Jobs that subclass the <code>nautobot.apps.jobs.JobHookReceiver</code> class. Job Hook Receivers are similar to normal Jobs except they are hard coded to accept only an <code>object_change</code> <a href="#variables">variable</a>. The <code>JobHookReceiver</code> class only implements one method called <code>receive_job_hook</code>.</p>
10580
10749
  <div class="admonition warning">
10581
- <p class="admonition-title">Warning</p>
10750
+ <p class="admonition-title">No support for <code>approval_required</code> at this time</p>
10582
10751
  <p>Requiring approval for execution of Job Hooks by setting the <code>Meta.approval_required</code> attribute to <code>True</code> on your <code>JobHookReceiver</code> subclass is not supported. The value of this attribute will be ignored. Support for requiring approval of Job Hooks will be added in a future release.</p>
10583
10752
  </div>
10584
10753
  <div class="admonition important">
10585
- <p class="admonition-title">Important</p>
10586
- <p>To prevent negatively impacting system performance through an infinite loop, a change that was made by a <code>JobHookReceiver</code> job will not trigger another <code>JobHookReceiver</code> job to run.</p>
10754
+ <p class="admonition-title">No recursive JobHookReceivers</p>
10755
+ <p>To prevent negatively impacting system performance through an infinite loop, a change that was made by a <code>JobHookReceiver</code> Job will not trigger another <code>JobHookReceiver</code> Job to run.</p>
10587
10756
  </div>
10588
10757
  <h3 id="example-job-hook-receiver">Example Job Hook Receiver<a class="headerlink" href="#example-job-hook-receiver" title="Permanent link">&para;</a></h3>
10589
10758
  <div class="highlight"><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
@@ -10724,7 +10893,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10724
10893
 
10725
10894
 
10726
10895
  <a href="https://blog.networktocode.com/blog/tags/nautobot" target="_blank" rel="noopener" title="Network to Code Blog" class="md-social__link">
10727
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M0 64c0-17.7 14.3-32 32-32 229.8 0 416 186.2 416 416 0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96 14.3 96 0 81.7 0 64m0 352a64 64 0 1 1 128 0 64 64 0 1 1-128 0m32-256c159.1 0 288 128.9 288 288 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224-17.7 0-32-14.3-32-32s14.3-32 32-32"/></svg>
10896
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M0 64c0-17.7 14.3-32 32-32 229.8 0 416 186.2 416 416 0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96 14.3 96 0 81.7 0 64m0 352a64 64 0 1 1 128 0 64 64 0 1 1-128 0m32-256c159.1 0 288 128.9 288 288 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224-17.7 0-32-14.3-32-32s14.3-32 32-32"/></svg>
10728
10897
  </a>
10729
10898
 
10730
10899
 
@@ -10732,7 +10901,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10732
10901
 
10733
10902
 
10734
10903
  <a href="https://www.youtube.com/playlist?list=PLjA0bhxgryJ2Ts4GJMDA-tPzVWEncv4pb" target="_blank" rel="noopener" title="Nautobot Videos" class="md-social__link">
10735
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305m-317.51 213.508V175.185l142.739 81.205z"/></svg>
10904
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305m-317.51 213.508V175.185l142.739 81.205z"/></svg>
10736
10905
  </a>
10737
10906
 
10738
10907
 
@@ -10740,7 +10909,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10740
10909
 
10741
10910
 
10742
10911
  <a href="https://www.networktocode.com/community/" target="_blank" rel="noopener" title="Network to Code Community" class="md-social__link">
10743
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1s21.16-47.06 47.06-47.06h47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06S448 171 448 196.9s-21.16 47.06-47.06 47.06h-47.06zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06S309 480 283.1 480s-47.06-21.16-47.06-47.06v-47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06s21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06z"/></svg>
10912
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1s21.16-47.06 47.06-47.06h47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06S448 171 448 196.9s-21.16 47.06-47.06 47.06h-47.06zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06S309 480 283.1 480s-47.06-21.16-47.06-47.06v-47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06s21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06z"/></svg>
10744
10913
  </a>
10745
10914
 
10746
10915
 
@@ -10748,7 +10917,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10748
10917
 
10749
10918
 
10750
10919
  <a href="https://github.com/nautobot/nautobot" target="_blank" rel="noopener" title="GitHub Repo" class="md-social__link">
10751
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
10920
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
10752
10921
  </a>
10753
10922
 
10754
10923
 
@@ -10756,7 +10925,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10756
10925
 
10757
10926
 
10758
10927
  <a href="https://twitter.com/networktocode" target="_blank" rel="noopener" title="Network to Code Twitter" class="md-social__link">
10759
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg>
10928
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg>
10760
10929
  </a>
10761
10930
 
10762
10931
  </div>
@@ -10771,10 +10940,10 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10771
10940
  </div>
10772
10941
 
10773
10942
 
10774
- <script id="__config" type="application/json">{"base": "../..", "features": ["content.code.annotate", "content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
10943
+ <script id="__config" type="application/json">{"base": "../..", "features": ["content.code.annotate", "content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "../../assets/javascripts/workers/search.f8cc74c7.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
10775
10944
 
10776
10945
 
10777
- <script src="../../assets/javascripts/bundle.83f73b43.min.js"></script>
10946
+ <script src="../../assets/javascripts/bundle.60a45f97.min.js"></script>
10778
10947
 
10779
10948
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
10780
10949