nautobot 2.3.13__py3-none-any.whl → 2.3.14__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 (295) hide show
  1. nautobot/circuits/tables.py +2 -1
  2. nautobot/core/filters.py +2 -0
  3. nautobot/core/jobs/cleanup.py +47 -11
  4. nautobot/core/templates/search.html +7 -0
  5. nautobot/core/testing/filters.py +20 -5
  6. nautobot/dcim/forms.py +6 -5
  7. nautobot/dcim/models/devices.py +1 -0
  8. nautobot/dcim/tests/test_forms.py +51 -2
  9. nautobot/extras/forms/mixins.py +10 -2
  10. nautobot/extras/jobs.py +6 -4
  11. nautobot/ipam/models.py +62 -11
  12. nautobot/ipam/tables.py +2 -2
  13. nautobot/ipam/tests/test_api.py +68 -1
  14. nautobot/ipam/tests/test_models.py +41 -0
  15. nautobot/project-static/docs/404.html +1 -1
  16. nautobot/project-static/docs/apps/index.html +1 -1
  17. nautobot/project-static/docs/apps/nautobot-apps.html +1 -1
  18. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +1 -1
  19. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +1 -1
  20. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1 -1
  21. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +1 -1
  22. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +1 -1
  23. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +1 -1
  24. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +1 -1
  25. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +1 -1
  26. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +1 -1
  27. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1 -1
  28. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1 -1
  29. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1 -1
  30. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1 -1
  31. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +7 -5
  32. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1 -1
  33. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +1 -1
  34. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +1 -1
  35. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1 -1
  36. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +2 -2
  37. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1 -1
  38. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +1 -1
  39. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +1 -1
  40. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1 -1
  41. nautobot/project-static/docs/development/apps/api/configuration-view.html +1 -1
  42. nautobot/project-static/docs/development/apps/api/database-backend-config.html +1 -1
  43. nautobot/project-static/docs/development/apps/api/models/django-admin.html +1 -1
  44. nautobot/project-static/docs/development/apps/api/models/global-search.html +1 -1
  45. nautobot/project-static/docs/development/apps/api/models/graphql.html +1 -1
  46. nautobot/project-static/docs/development/apps/api/models/index.html +1 -1
  47. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +1 -1
  48. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +1 -1
  49. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +1 -1
  50. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +1 -1
  51. nautobot/project-static/docs/development/apps/api/platform-features/index.html +1 -1
  52. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +1 -1
  53. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +1 -1
  54. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +1 -1
  55. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +1 -1
  56. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +1 -1
  57. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +1 -1
  58. nautobot/project-static/docs/development/apps/api/prometheus.html +1 -1
  59. nautobot/project-static/docs/development/apps/api/setup.html +1 -1
  60. nautobot/project-static/docs/development/apps/api/testing.html +1 -1
  61. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +1 -1
  62. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +1 -1
  63. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +1 -1
  64. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +1 -1
  65. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +1 -1
  66. nautobot/project-static/docs/development/apps/api/views/base-template.html +1 -1
  67. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +1 -1
  68. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +1 -1
  69. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +1 -1
  70. nautobot/project-static/docs/development/apps/api/views/index.html +1 -1
  71. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +1 -1
  72. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +1 -1
  73. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +1 -1
  74. nautobot/project-static/docs/development/apps/api/views/notes.html +1 -1
  75. nautobot/project-static/docs/development/apps/api/views/rest-api.html +1 -1
  76. nautobot/project-static/docs/development/apps/api/views/urls.html +1 -1
  77. nautobot/project-static/docs/development/apps/index.html +1 -1
  78. nautobot/project-static/docs/development/apps/migration/code-updates.html +1 -1
  79. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +1 -1
  80. nautobot/project-static/docs/development/apps/migration/from-v1.html +1 -1
  81. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +1 -1
  82. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +1 -1
  83. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +1 -1
  84. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +1 -1
  85. nautobot/project-static/docs/development/apps/porting-from-netbox.html +1 -1
  86. nautobot/project-static/docs/development/core/application-registry.html +1 -1
  87. nautobot/project-static/docs/development/core/best-practices.html +1 -1
  88. nautobot/project-static/docs/development/core/bootstrap-ui.html +1 -1
  89. nautobot/project-static/docs/development/core/caching.html +1 -1
  90. nautobot/project-static/docs/development/core/controllers.html +1 -1
  91. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +1 -1
  92. nautobot/project-static/docs/development/core/generic-views.html +1 -1
  93. nautobot/project-static/docs/development/core/getting-started.html +154 -140
  94. nautobot/project-static/docs/development/core/homepage.html +1 -1
  95. nautobot/project-static/docs/development/core/index.html +1 -1
  96. nautobot/project-static/docs/development/core/model-checklist.html +1 -1
  97. nautobot/project-static/docs/development/core/model-features.html +1 -1
  98. nautobot/project-static/docs/development/core/natural-keys.html +1 -1
  99. nautobot/project-static/docs/development/core/navigation-menu.html +1 -1
  100. nautobot/project-static/docs/development/core/release-checklist.html +1 -1
  101. nautobot/project-static/docs/development/core/role-internals.html +1 -1
  102. nautobot/project-static/docs/development/core/settings.html +1 -1
  103. nautobot/project-static/docs/development/core/style-guide.html +1 -1
  104. nautobot/project-static/docs/development/core/templates.html +1 -1
  105. nautobot/project-static/docs/development/core/testing.html +1 -1
  106. nautobot/project-static/docs/development/core/user-preferences.html +1 -1
  107. nautobot/project-static/docs/development/index.html +1 -1
  108. nautobot/project-static/docs/development/jobs/index.html +142 -118
  109. nautobot/project-static/docs/development/jobs/migration/from-v1.html +1 -1
  110. nautobot/project-static/docs/index.html +1 -1
  111. nautobot/project-static/docs/overview/application_stack.html +1 -1
  112. nautobot/project-static/docs/overview/design_philosophy.html +1 -1
  113. nautobot/project-static/docs/release-notes/index.html +1 -1
  114. nautobot/project-static/docs/release-notes/version-1.0.html +1 -1
  115. nautobot/project-static/docs/release-notes/version-1.1.html +1 -1
  116. nautobot/project-static/docs/release-notes/version-1.2.html +1 -1
  117. nautobot/project-static/docs/release-notes/version-1.3.html +1 -1
  118. nautobot/project-static/docs/release-notes/version-1.4.html +1 -1
  119. nautobot/project-static/docs/release-notes/version-1.5.html +1 -1
  120. nautobot/project-static/docs/release-notes/version-1.6.html +1 -1
  121. nautobot/project-static/docs/release-notes/version-2.0.html +1 -1
  122. nautobot/project-static/docs/release-notes/version-2.1.html +1 -1
  123. nautobot/project-static/docs/release-notes/version-2.2.html +1 -1
  124. nautobot/project-static/docs/release-notes/version-2.3.html +332 -181
  125. nautobot/project-static/docs/requirements.txt +1 -1
  126. nautobot/project-static/docs/search/search_index.json +1 -1
  127. nautobot/project-static/docs/sitemap.xml +270 -270
  128. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  129. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +1 -1
  130. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +1 -1
  131. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +1 -1
  132. nautobot/project-static/docs/user-guide/administration/configuration/index.html +1 -1
  133. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +1 -1
  134. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +1 -1
  135. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +1 -1
  136. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +1 -1
  137. nautobot/project-static/docs/user-guide/administration/guides/docker.html +1 -1
  138. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +1 -1
  139. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +1 -1
  140. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +1 -1
  141. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +1 -1
  142. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +1 -1
  143. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +1 -1
  144. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +1 -1
  145. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +1 -1
  146. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +1 -1
  147. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +1 -1
  148. nautobot/project-static/docs/user-guide/administration/installation/index.html +1 -1
  149. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +1 -1
  150. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +1 -1
  151. nautobot/project-static/docs/user-guide/administration/installation/services.html +1 -1
  152. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +1 -1
  153. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +1 -1
  154. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +1 -1
  155. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +1 -1
  156. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +1 -1
  157. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +1 -1
  158. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +1 -1
  159. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +1 -1
  160. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +1 -1
  161. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +1 -1
  162. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +1 -1
  163. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +1 -1
  164. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +1 -1
  165. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +1 -1
  166. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +1 -1
  167. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +1 -1
  168. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +1 -1
  169. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +1 -1
  170. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +1 -1
  171. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +1 -1
  172. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +1 -1
  173. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +1 -1
  174. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +1 -1
  175. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +1 -1
  176. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +1 -1
  177. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +1 -1
  178. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +1 -1
  179. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +1 -1
  180. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +1 -1
  181. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +1 -1
  182. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +1 -1
  183. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +1 -1
  184. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +1 -1
  185. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +1 -1
  186. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +1 -1
  187. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +1 -1
  188. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +1 -1
  189. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +1 -1
  190. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +1 -1
  191. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +1 -1
  192. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +1 -1
  193. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +1 -1
  194. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +1 -1
  195. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +1 -1
  196. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +1 -1
  197. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +1 -1
  198. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +1 -1
  199. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +1 -1
  200. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +1 -1
  201. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +1 -1
  202. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +1 -1
  203. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +1 -1
  204. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +1 -1
  205. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +1 -1
  206. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +1 -1
  207. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +1 -1
  208. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +1 -1
  209. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +1 -1
  210. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +1 -1
  211. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +1 -1
  212. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +1 -1
  213. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +1 -1
  214. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +1 -1
  215. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +1 -1
  216. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +1 -1
  217. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +1 -1
  218. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +1 -1
  219. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +1 -1
  220. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +1 -1
  221. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +1 -1
  222. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +1 -1
  223. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +1 -1
  224. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +1 -1
  225. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +1 -1
  226. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +1 -1
  227. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +1 -1
  228. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +1 -1
  229. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +1 -1
  230. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +1 -1
  231. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +1 -1
  232. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +1 -1
  233. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +1 -1
  234. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +1 -1
  235. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +1 -1
  236. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +1 -1
  237. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +1 -1
  238. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +1 -1
  239. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +1 -1
  240. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +1 -1
  241. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +1 -1
  242. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +1 -1
  243. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +1 -1
  244. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +1 -1
  245. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +1 -1
  246. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +1 -1
  247. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +1 -1
  248. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +1 -1
  249. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +1 -1
  250. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +1 -1
  251. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +1 -1
  252. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +1 -1
  253. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +1 -1
  254. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +1 -1
  255. nautobot/project-static/docs/user-guide/index.html +1 -1
  256. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +1 -1
  257. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +1 -1
  258. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +1 -1
  259. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +1 -1
  260. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1 -1
  261. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +1 -1
  262. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +1 -1
  263. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +1 -1
  264. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +1 -1
  265. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +1 -1
  266. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +1 -1
  267. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +1 -1
  268. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +1 -1
  269. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +1 -1
  270. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +1 -1
  271. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +1 -1
  272. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +1 -1
  273. nautobot/project-static/docs/user-guide/platform-functionality/note.html +1 -1
  274. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +1 -1
  275. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +1 -1
  276. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +1 -1
  277. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +1 -1
  278. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +1 -1
  279. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +1 -1
  280. nautobot/project-static/docs/user-guide/platform-functionality/role.html +1 -1
  281. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +1 -1
  282. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +1 -1
  283. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +1 -1
  284. nautobot/project-static/docs/user-guide/platform-functionality/status.html +1 -1
  285. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +1 -1
  286. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +1 -1
  287. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +1 -1
  288. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +1 -1
  289. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +1 -1
  290. {nautobot-2.3.13.dist-info → nautobot-2.3.14.dist-info}/METADATA +1 -1
  291. {nautobot-2.3.13.dist-info → nautobot-2.3.14.dist-info}/RECORD +295 -295
  292. {nautobot-2.3.13.dist-info → nautobot-2.3.14.dist-info}/LICENSE.txt +0 -0
  293. {nautobot-2.3.13.dist-info → nautobot-2.3.14.dist-info}/NOTICE +0 -0
  294. {nautobot-2.3.13.dist-info → nautobot-2.3.14.dist-info}/WHEEL +0 -0
  295. {nautobot-2.3.13.dist-info → nautobot-2.3.14.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.47">
21
+ <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.48">
22
22
 
23
23
 
24
24
 
@@ -8608,6 +8608,15 @@
8608
8608
  <nav class="md-nav" aria-label="Writing Jobs">
8609
8609
  <ul class="md-nav__list">
8610
8610
 
8611
+ <li class="md-nav__item">
8612
+ <a href="#introduction-to-writing-jobs" class="md-nav__link">
8613
+ <span class="md-ellipsis">
8614
+ Introduction to Writing Jobs
8615
+ </span>
8616
+ </a>
8617
+
8618
+ </li>
8619
+
8611
8620
  <li class="md-nav__item">
8612
8621
  <a href="#job-registration" class="md-nav__link">
8613
8622
  <span class="md-ellipsis">
@@ -9069,11 +9078,11 @@
9069
9078
  <li class="md-nav__item">
9070
9079
  <a href="#debugging-job-performance" class="md-nav__link">
9071
9080
  <span class="md-ellipsis">
9072
- Debugging job performance
9081
+ Debugging Job Performance
9073
9082
  </span>
9074
9083
  </a>
9075
9084
 
9076
- <nav class="md-nav" aria-label="Debugging job performance">
9085
+ <nav class="md-nav" aria-label="Debugging Job Performance">
9077
9086
  <ul class="md-nav__list">
9078
9087
 
9079
9088
  <li class="md-nav__item">
@@ -9100,6 +9109,15 @@
9100
9109
  <nav class="md-nav" aria-label="Example Jobs">
9101
9110
  <ul class="md-nav__list">
9102
9111
 
9112
+ <li class="md-nav__item">
9113
+ <a href="#example-everything-job" class="md-nav__link">
9114
+ <span class="md-ellipsis">
9115
+ Example "Everything" Job
9116
+ </span>
9117
+ </a>
9118
+
9119
+ </li>
9120
+
9103
9121
  <li class="md-nav__item">
9104
9122
  <a href="#creating-objects-for-a-planned-location" class="md-nav__link">
9105
9123
  <span class="md-ellipsis">
@@ -9218,30 +9236,24 @@
9218
9236
 
9219
9237
  <h1 id="jobs">Jobs<a class="headerlink" href="#jobs" title="Permanent link">&para;</a></h1>
9220
9238
  <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>
9221
- <div class="admonition tip">
9222
- <p class="admonition-title">Tip</p>
9239
+ <details class="tip">
9240
+ <summary>More about Job class source code loading</summary>
9223
9241
  <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>
9224
- </div>
9225
- <div class="admonition info">
9226
- <p class="admonition-title">Info</p>
9227
9242
  <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>
9228
- </div>
9229
- <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>
9230
- <details class="version-changed">
9231
- <summary>Changed in version 2.0.0</summary>
9232
- <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>
9233
9243
  </details>
9244
+ <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>
9245
+ <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>
9234
9246
  <h2 id="installing-jobs">Installing Jobs<a class="headerlink" href="#installing-jobs" title="Permanent link">&para;</a></h2>
9235
9247
  <p>Jobs may be installed in one of three ways:</p>
9236
9248
  <ul>
9237
9249
  <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>
9238
- <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>
9250
+ <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>
9239
9251
  <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>
9240
9252
  </ul>
9241
9253
  </li>
9242
9254
  <li>Imported from an external <a href="../../user-guide/platform-functionality/gitrepository.html#jobs">Git repository</a>.<ul>
9243
- <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>
9244
- <li>All git repositories providing jobs must include a <code>__init__.py</code> file at the root of the repository.</li>
9255
+ <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>
9256
+ <li>All git repositories providing Jobs must include a <code>__init__.py</code> file at the root of the repository.</li>
9245
9257
  <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>
9246
9258
  </ul>
9247
9259
  </li>
@@ -9250,50 +9262,59 @@
9250
9262
  </ul>
9251
9263
  </li>
9252
9264
  </ul>
9253
- <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>
9254
- <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>
9265
+ <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>
9266
+ <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>
9255
9267
  <details class="version-changed">
9256
- <summary>Changed in version 2.0.0</summary>
9257
- <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>
9268
+ <summary>Changed in version 2.0.0 — <code>register_jobs()</code> must be called</summary>
9269
+ <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>
9258
9270
  </details>
9259
9271
  <h2 id="writing-jobs">Writing Jobs<a class="headerlink" href="#writing-jobs" title="Permanent link">&para;</a></h2>
9272
+ <h3 id="introduction-to-writing-jobs">Introduction to Writing Jobs<a class="headerlink" href="#introduction-to-writing-jobs" title="Permanent link">&para;</a></h3>
9260
9273
  <div class="admonition warning">
9261
9274
  <p class="admonition-title">Warning</p>
9262
- <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>
9275
+ <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>
9263
9276
  </div>
9264
- <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>
9277
+ <p>The most basic structure of a Python file providing one or more Jobs is as follows:</p>
9278
+ <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>
9265
9279
  <a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>
9266
- <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>
9267
- <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="o">...</span>
9268
- <a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>
9269
- <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>
9270
- <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="o">...</span>
9271
- <a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>
9272
- <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>
9273
- <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="o">...</span>
9274
- <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
9275
- <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>
9280
+ <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>
9281
+ <a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>
9282
+ <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>
9283
+ <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>
9284
+ <a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="c1"># metadata attributes go here</span>
9285
+ <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>
9286
+ <a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="c1"># ... etc.</span>
9287
+ <a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>
9288
+ <a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="c1"># input variable definitions go here</span>
9289
+ <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>
9290
+ <a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a> <span class="c1"># ... etc.</span>
9291
+ <a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a>
9292
+ <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>
9293
+ <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>
9294
+ <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>
9295
+ <a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a>
9296
+ <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>
9276
9297
  </code></pre></div>
9277
- <p>Each job class will implement some or all of the following components:</p>
9298
+ <p>Each Job class will implement some or all of the following components:</p>
9278
9299
  <ul>
9279
- <li>Module and class attributes, providing for default behavior, documentation and discoverability</li>
9280
- <li>a set of variables for user input via the Nautobot UI (if your job requires any user inputs)</li>
9281
- <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>
9282
- <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>
9300
+ <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>
9301
+ <li>A set of <a href="#variables">variables</a> for user input via the Nautobot UI or API.</li>
9302
+ <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>
9303
+ <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>
9283
9304
  </ul>
9284
- <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>
9305
+ <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>
9285
9306
  <div class="admonition note">
9286
- <p class="admonition-title">Note</p>
9307
+ <p class="admonition-title">About detection of changes while developing a Job</p>
9287
9308
  <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>
9288
9309
  <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>
9289
9310
  </div>
9290
9311
  <h3 id="job-registration">Job Registration<a class="headerlink" href="#job-registration" title="Permanent link">&para;</a></h3>
9291
9312
  <details class="version-changed">
9292
- <summary>Changed in version 2.0.0</summary>
9313
+ <summary>Changed in version 2.0.0 — <code>register_jobs()</code> is now required</summary>
9293
9314
  </details>
9294
- <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>
9315
+ <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>
9295
9316
  <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>
9296
- <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>
9317
+ <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>
9297
9318
  <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>
9298
9319
  </code></pre></div>
9299
9320
  <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>
@@ -9303,12 +9324,12 @@
9303
9324
  <a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a>
9304
9325
  <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>
9305
9326
  </code></pre></div>
9306
- <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>
9307
- <p>If not using submodules, you should register your job in the file where your job is defined.</p>
9308
- <p>Examples of the different directory structures when registering jobs in Git repositories: </p>
9327
+ <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>
9328
+ <p>If not using submodules, you should register your Job in the file where it is defined.</p>
9329
+ <p>Examples of the different directory structures when registering Jobs in Git repositories:</p>
9309
9330
  <div class="admonition note">
9310
- <p class="admonition-title">Note</p>
9311
- <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>
9331
+ <p class="admonition-title"><code>__init__.py</code></p>
9332
+ <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>
9312
9333
  </div>
9313
9334
  <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>.
9314
9335
  <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>├── __init__.py
@@ -9321,7 +9342,7 @@
9321
9342
  <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> └── my_job_module.py
9322
9343
  </code></pre></div>
9323
9344
  <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>
9324
- <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>
9345
+ <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>
9325
9346
  <h3 id="reserved-attribute-names">Reserved Attribute Names<a class="headerlink" href="#reserved-attribute-names" title="Permanent link">&para;</a></h3>
9326
9347
  <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>
9327
9348
  <div class="admonition example">
@@ -9501,21 +9522,21 @@
9501
9522
  </table>
9502
9523
  <h3 id="module-metadata-attributes">Module Metadata Attributes<a class="headerlink" href="#module-metadata-attributes" title="Permanent link">&para;</a></h3>
9503
9524
  <h4 id="name-grouping"><code>name</code> (Grouping)<a class="headerlink" href="#name-grouping" title="Permanent link">&para;</a></h4>
9504
- <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>
9525
+ <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>
9505
9526
  <div class="admonition note">
9506
9527
  <p class="admonition-title">Note</p>
9507
9528
  <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>
9508
9529
  </div>
9509
9530
  <h3 id="class-metadata-attributes">Class Metadata Attributes<a class="headerlink" href="#class-metadata-attributes" title="Permanent link">&para;</a></h3>
9510
- <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>
9531
+ <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>
9511
9532
  <h4 id="name"><code>name</code><a class="headerlink" href="#name" title="Permanent link">&para;</a></h4>
9512
- <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>
9533
+ <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>
9513
9534
  <div class="admonition note">
9514
9535
  <p class="admonition-title">Note</p>
9515
9536
  <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>
9516
9537
  </div>
9517
9538
  <h4 id="description"><code>description</code><a class="headerlink" href="#description" title="Permanent link">&para;</a></h4>
9518
- <p>An optional human-friendly description of what this job does.
9539
+ <p>An optional human-friendly description of what this Job does.
9519
9540
  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>
9520
9541
  <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>
9521
9542
  <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>
@@ -9527,63 +9548,64 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
9527
9548
  <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>
9528
9549
  <a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a><span class="s2"> &quot;&quot;&quot;</span>
9529
9550
  </code></pre></div>
9530
- <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>
9551
+ <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>
9531
9552
  <h4 id="approval_required"><code>approval_required</code><a class="headerlink" href="#approval_required" title="Permanent link">&para;</a></h4>
9532
9553
  <p>Default: <code>False</code></p>
9533
- <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>
9554
+ <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>
9534
9555
  <h4 id="dryrun_default"><code>dryrun_default</code><a class="headerlink" href="#dryrun_default" title="Permanent link">&para;</a></h4>
9535
9556
  <details class="version-changed">
9536
- <summary>Changed in version 2.0.0</summary>
9537
- <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>
9557
+ <summary>Changed in version 2.0.0 — Replacement for <code>commit_default</code></summary>
9558
+ <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>
9538
9559
  </details>
9539
9560
  <p>Default: <code>False</code></p>
9540
- <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>
9561
+ <p>If the Job implements a <a href="#dryrunvar"><code>DryRunVar</code></a>, what its default value should be.
9562
+ 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>
9541
9563
  <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>
9542
9564
  <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>
9543
9565
  <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>
9544
9566
  </code></pre></div>
9545
9567
  <h4 id="field_order"><code>field_order</code><a class="headerlink" href="#field_order" title="Permanent link">&para;</a></h4>
9546
9568
  <p>Default: <code>[]</code></p>
9547
- <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>
9569
+ <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>
9548
9570
  <h4 id="has_sensitive_variables"><code>has_sensitive_variables</code><a class="headerlink" href="#has_sensitive_variables" title="Permanent link">&para;</a></h4>
9549
9571
  <details class="version-added">
9550
9572
  <summary>Added in version 1.3.10</summary>
9551
9573
  </details>
9552
9574
  <p>Default: <code>True</code></p>
9553
- <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>
9554
- <p>Important notes about jobs with sensitive variables:</p>
9575
+ <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>
9576
+ <p>Important notes about Jobs with sensitive variables:</p>
9555
9577
  <ul>
9556
- <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>
9557
- <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>
9578
+ <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>
9579
+ <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>
9558
9580
  </ul>
9559
9581
  <h4 id="hidden"><code>hidden</code><a class="headerlink" href="#hidden" title="Permanent link">&para;</a></h4>
9560
9582
  <p>Default: <code>False</code></p>
9561
- <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>
9562
- <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>
9563
- <p>Important notes about hidden jobs:</p>
9583
+ <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>
9584
+ <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>
9585
+ <p>Important notes about hidden Jobs:</p>
9564
9586
  <ul>
9565
9587
  <li>This is merely hiding them by default from the web interface. It is NOT a security feature.</li>
9566
- <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>
9567
- <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>
9568
- <li>Hidden jobs can still be executed through the UI or the REST API given the appropriate URL.</li>
9569
- <li>Results for hidden jobs will still appear in the Job Results list after they are run.</li>
9588
+ <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>
9589
+ <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>
9590
+ <li>Hidden Jobs can still be executed through the UI or the REST API given the appropriate URL.</li>
9591
+ <li>Results for hidden Jobs will still appear in the Job Results list after they are run.</li>
9570
9592
  </ul>
9571
9593
  <h4 id="read_only"><code>read_only</code><a class="headerlink" href="#read_only" title="Permanent link">&para;</a></h4>
9572
9594
  <details class="version-added">
9573
9595
  <summary>Added in version 1.1.0</summary>
9574
9596
  </details>
9575
9597
  <details class="version-changed">
9576
- <summary>Changed in version 2.0.0</summary>
9577
- <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>
9598
+ <summary>Changed in version 2.0.0 — No automatic functionality</summary>
9599
+ <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>
9578
9600
  </details>
9579
9601
  <p>Default: <code>False</code></p>
9580
- <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>
9602
+ <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>
9581
9603
  <h4 id="soft_time_limit"><code>soft_time_limit</code><a class="headerlink" href="#soft_time_limit" title="Permanent link">&para;</a></h4>
9582
9604
  <details class="version-added">
9583
9605
  <summary>Added in version 1.3.0</summary>
9584
9606
  </details>
9585
- <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>
9586
- <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>
9607
+ <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>
9608
+ <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>
9587
9609
  <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>
9588
9610
  <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>
9589
9611
  <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>
@@ -9606,16 +9628,16 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
9606
9628
  <summary>Added in version 1.5.0</summary>
9607
9629
  </details>
9608
9630
  <p>Default: <code>[]</code></p>
9609
- <p>A list of task 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 queue</a> (<code>default</code> unless changed by an administrator). The first queue in the list will be used if a queue is not specified in a job run API call.</p>
9631
+ <p>A list of task 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 queue</a> (<code>default</code> unless changed by an administrator). The first queue in the list will be used if a queue is not specified in a Job run API call.</p>
9610
9632
  <div class="admonition note">
9611
9633
  <p class="admonition-title">Note</p>
9612
- <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>
9634
+ <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>
9613
9635
  </div>
9614
9636
  <h4 id="template_name"><code>template_name</code><a class="headerlink" href="#template_name" title="Permanent link">&para;</a></h4>
9615
9637
  <details class="version-added">
9616
9638
  <summary>Added in version 1.4.0</summary>
9617
9639
  </details>
9618
- <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>
9640
+ <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>
9619
9641
  <p>A template can provide additional JavaScript, CSS, or even display HTML. A good starting template would be:</p>
9620
9642
  <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; %}
9621
9643
  <a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>
@@ -9633,7 +9655,7 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
9633
9655
  <a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a>{% endblock javascript %}
9634
9656
  </code></pre></div>
9635
9657
  <details class="version-added">
9636
- <summary>Added in version 2.2.0</summary>
9658
+ <summary>Added in version 2.2.0 — Additional blocks</summary>
9637
9659
  <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>
9638
9660
  </details>
9639
9661
  <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>
@@ -9642,7 +9664,7 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
9642
9664
  <summary>Added in version 1.3.0</summary>
9643
9665
  </details>
9644
9666
  <p>An int or float value, in seconds, which can be used to override the
9645
- 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>
9667
+ 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>
9646
9668
  <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>
9647
9669
  <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>
9648
9670
  <a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>
@@ -9658,11 +9680,11 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
9658
9680
  <a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a> <span class="n">job_code</span><span class="p">()</span>
9659
9681
  </code></pre></div>
9660
9682
  <div class="admonition note">
9661
- <p class="admonition-title">Note</p>
9662
- <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>
9683
+ <p class="admonition-title"><code>time_limit</code> versus <code>soft_time_limit</code></p>
9684
+ <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>
9663
9685
  </div>
9664
9686
  <h3 id="variables">Variables<a class="headerlink" href="#variables" title="Permanent link">&para;</a></h3>
9665
- <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>
9687
+ <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>
9666
9688
  <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>
9667
9689
  <a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>
9668
9690
  <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>
@@ -9675,7 +9697,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
9675
9697
  </code></pre></div>
9676
9698
  <p>The remainder of this section documents the various supported variable types and how to make use of them.</p>
9677
9699
  <h4 id="default-variable-options">Default Variable Options<a class="headerlink" href="#default-variable-options" title="Permanent link">&para;</a></h4>
9678
- <p>All job variables support the following default options:</p>
9700
+ <p>All Job variables support the following default options:</p>
9679
9701
  <ul>
9680
9702
  <li><code>default</code> - The field's default value</li>
9681
9703
  <li><code>description</code> - A brief user-friendly description of the field</li>
@@ -9697,7 +9719,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
9697
9719
  <details class="version-added">
9698
9720
  <summary>Added in version 2.1.0</summary>
9699
9721
  </details>
9700
- <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>
9722
+ <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>
9701
9723
  <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>
9702
9724
  <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>
9703
9725
  <a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
@@ -9705,7 +9727,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
9705
9727
  <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>
9706
9728
  <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>
9707
9729
  </code></pre></div>
9708
- <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>
9730
+ <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>
9709
9731
  <h4 id="integervar"><code>IntegerVar</code><a class="headerlink" href="#integervar" title="Permanent link">&para;</a></h4>
9710
9732
  <p>Stores a numeric integer. Options include:</p>
9711
9733
  <ul>
@@ -9715,7 +9737,7 @@ default <a href="../../user-guide/administration/configuration/settings.html#cel
9715
9737
  <h4 id="booleanvar"><code>BooleanVar</code><a class="headerlink" href="#booleanvar" title="Permanent link">&para;</a></h4>
9716
9738
  <p>A true/false flag. This field has no options beyond the defaults listed above.</p>
9717
9739
  <h4 id="dryrunvar"><code>DryRunVar</code><a class="headerlink" href="#dryrunvar" title="Permanent link">&para;</a></h4>
9718
- <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>
9740
+ <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>
9719
9741
  <h4 id="choicevar"><code>ChoiceVar</code><a class="headerlink" href="#choicevar" title="Permanent link">&para;</a></h4>
9720
9742
  <p>A set of choices from which the user can select one.</p>
9721
9743
  <ul>
@@ -9792,7 +9814,7 @@ Another example of using the nested reference would be to access <a href="../../
9792
9814
  <h4 id="multiobjectvar"><code>MultiObjectVar</code><a class="headerlink" href="#multiobjectvar" title="Permanent link">&para;</a></h4>
9793
9815
  <p>Similar to <code>ObjectVar</code>, but allows for the selection of multiple objects.</p>
9794
9816
  <h4 id="filevar"><code>FileVar</code><a class="headerlink" href="#filevar" title="Permanent link">&para;</a></h4>
9795
- <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>
9817
+ <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>
9796
9818
  <h4 id="ipaddressvar"><code>IPAddressVar</code><a class="headerlink" href="#ipaddressvar" title="Permanent link">&para;</a></h4>
9797
9819
  <p>An IPv4 or IPv6 address, without a mask. Returns a <code>netaddr.IPAddress</code> object.</p>
9798
9820
  <h4 id="ipaddresswithmaskvar"><code>IPAddressWithMaskVar</code><a class="headerlink" href="#ipaddresswithmaskvar" title="Permanent link">&para;</a></h4>
@@ -9807,14 +9829,14 @@ Another example of using the nested reference would be to access <a href="../../
9807
9829
  <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>
9808
9830
  <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>
9809
9831
  <details class="version-removed">
9810
- <summary>Removed in version 2.0.0</summary>
9832
+ <summary>Removed in version 2.0.0 — Removal of <code>test</code> and <code>post_run</code> special methods</summary>
9811
9833
  <p>The NetBox backwards compatible <code>test_*()</code> and <code>post_run()</code> special methods have been removed.</p>
9812
9834
  </details>
9813
9835
  <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>
9814
9836
  <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>
9815
9837
  <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>
9816
9838
  <h4 id="the-run-method">The <code>run()</code> Method<a class="headerlink" href="#the-run-method" title="Permanent link">&para;</a></h4>
9817
- <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>
9839
+ <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>
9818
9840
  <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>
9819
9841
  <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>
9820
9842
  <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>
@@ -9825,13 +9847,13 @@ Another example of using the nested reference would be to access <a href="../../
9825
9847
  <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>
9826
9848
  <a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="o">...</span>
9827
9849
  </code></pre></div>
9828
- <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>
9850
+ <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>
9829
9851
  <div class="admonition warning">
9830
- <p class="admonition-title">Warning</p>
9852
+ <p class="admonition-title">Use <code>validated_save()</code> where applicable</p>
9831
9853
  <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>
9832
9854
  </div>
9833
9855
  <div class="admonition warning">
9834
- <p class="admonition-title">Warning</p>
9856
+ <p class="admonition-title">Be cautious around bulk operations</p>
9835
9857
  <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>
9836
9858
  </div>
9837
9859
  <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>
@@ -9845,8 +9867,8 @@ Another example of using the nested reference would be to access <a href="../../
9845
9867
  <details class="version-changed">
9846
9868
  <summary>Changed in version 2.0.0</summary>
9847
9869
  </details>
9848
- <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>
9849
- <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>
9870
+ <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>
9871
+ <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>
9850
9872
  <p>The logger accepts an <code>extra</code> kwarg that you can optionally set for the following features:</p>
9851
9873
  <ul>
9852
9874
  <li><code>grouping</code>- Replaces the <code>active_test</code> Job property in Nautobot v1.X</li>
@@ -9875,16 +9897,16 @@ Another example of using the nested reference would be to access <a href="../../
9875
9897
  </div>
9876
9898
  <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>
9877
9899
  <details class="version-changed">
9878
- <summary>Changed in version 1.3.4</summary>
9879
- <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>
9900
+ <summary>Changed in version 1.3.4 — Log entry sanitization</summary>
9901
+ <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>
9880
9902
  </details>
9881
9903
  <details class="version-changed">
9882
- <summary>Changed in version 2.0.0</summary>
9883
- <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>
9904
+ <summary>Changed in version 2.0.0 — Significant API changes</summary>
9905
+ <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>
9884
9906
  </details>
9885
9907
  <details class="version-changed">
9886
9908
  <summary>Changed in version 2.0.0</summary>
9887
- <p>The <code>AbortTransaction</code> class was moved from the <code>nautobot.utilities.exceptions</code> module to <code>nautobot.core.exceptions</code>.</p>
9909
+ <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>
9888
9910
  </details>
9889
9911
  <h3 id="file-output">File Output<a class="headerlink" href="#file-output" title="Permanent link">&para;</a></h3>
9890
9912
  <details class="version-added">
@@ -9901,8 +9923,8 @@ Another example of using the nested reference would be to access <a href="../../
9901
9923
  <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>
9902
9924
  <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>
9903
9925
  <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>
9904
- <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>
9905
- <p>As an example, the following job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
9926
+ <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>
9927
+ <p>As an example, the following Job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
9906
9928
  <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>
9907
9929
  <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>
9908
9930
  <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>
@@ -9915,10 +9937,10 @@ Another example of using the nested reference would be to access <a href="../../
9915
9937
  </code></pre></div>
9916
9938
  <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>
9917
9939
  <details class="version-changed">
9918
- <summary>Changed in version 2.0.0</summary>
9940
+ <summary>Changed in version 2.0.0 — Significant API change</summary>
9919
9941
  <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>
9920
9942
  </details>
9921
- <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>
9943
+ <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>
9922
9944
  <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>
9923
9945
  <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>
9924
9946
  <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>
@@ -9940,7 +9962,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9940
9962
  </details>
9941
9963
  <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>
9942
9964
  <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>
9943
- <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>
9965
+ <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>
9944
9966
  <p>A simple example of a Job test case might look like the following:</p>
9945
9967
  <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>
9946
9968
  <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>
@@ -9962,15 +9984,15 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9962
9984
  <p class="admonition-title">Tip</p>
9963
9985
  <p>For more advanced examples refer to the Nautobot source code, specifically <code>nautobot/extras/tests/test_jobs.py</code>.</p>
9964
9986
  </div>
9965
- <h2 id="debugging-job-performance">Debugging job performance<a class="headerlink" href="#debugging-job-performance" title="Permanent link">&para;</a></h2>
9987
+ <h2 id="debugging-job-performance">Debugging Job Performance<a class="headerlink" href="#debugging-job-performance" title="Permanent link">&para;</a></h2>
9966
9988
  <details class="version-added">
9967
9989
  <summary>Added in version 1.5.17</summary>
9968
9990
  </details>
9969
- <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>
9970
- <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>
9991
+ <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>
9992
+ <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>
9971
9993
  <div class="admonition note">
9972
9994
  <p class="admonition-title">Note</p>
9973
- <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>
9995
+ <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>
9974
9996
  </div>
9975
9997
  <h3 id="reading-profiling-reports">Reading profiling reports<a class="headerlink" href="#reading-profiling-reports" title="Permanent link">&para;</a></h3>
9976
9998
  <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>
@@ -9979,16 +10001,18 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9979
10001
  <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>
9980
10002
  <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>
9981
10003
  </code></pre></div>
9982
- <p>This will print the 10 functions that the job execution spent the most time in - adapt this to your needs!</p>
10004
+ <p>This will print the 10 functions that the Job execution spent the most time in - adapt this to your needs!</p>
9983
10005
  <h2 id="example-jobs">Example Jobs<a class="headerlink" href="#example-jobs" title="Permanent link">&para;</a></h2>
10006
+ <h3 id="example-everything-job">Example "Everything" Job<a class="headerlink" href="#example-everything-job" title="Permanent link">&para;</a></h3>
10007
+ <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>
9984
10008
  <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>
9985
- <p>This job prompts the user for three variables:</p>
10009
+ <p>This Job prompts the user for three variables:</p>
9986
10010
  <ul>
9987
10011
  <li>The name of the new location</li>
9988
10012
  <li>The device model (a filtered list of defined device types)</li>
9989
10013
  <li>The number of access switches to create</li>
9990
10014
  </ul>
9991
- <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>
10015
+ <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>
9992
10016
  <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>
9993
10017
  <a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>
9994
10018
  <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>
@@ -10048,7 +10072,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10048
10072
  <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>
10049
10073
  </code></pre></div>
10050
10074
  <h3 id="device-validation">Device validation<a class="headerlink" href="#device-validation" title="Permanent link">&para;</a></h3>
10051
- <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>
10075
+ <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>
10052
10076
  <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>
10053
10077
  <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>
10054
10078
  <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>
@@ -10101,9 +10125,9 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10101
10125
  <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>
10102
10126
  </code></pre></div>
10103
10127
  <h2 id="job-button-receivers">Job Button Receivers<a class="headerlink" href="#job-button-receivers" title="Permanent link">&para;</a></h2>
10104
- <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>
10128
+ <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>
10105
10129
  <div class="admonition note">
10106
- <p class="admonition-title">Note</p>
10130
+ <p class="admonition-title">Disabled by default just like other Jobs</p>
10107
10131
  <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>
10108
10132
  </div>
10109
10133
  <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>
@@ -10166,14 +10190,14 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
10166
10190
  <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>
10167
10191
  </code></pre></div>
10168
10192
  <h2 id="job-hook-receivers">Job Hook Receivers<a class="headerlink" href="#job-hook-receivers" title="Permanent link">&para;</a></h2>
10169
- <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>
10193
+ <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>
10170
10194
  <div class="admonition warning">
10171
- <p class="admonition-title">Warning</p>
10195
+ <p class="admonition-title">No support for <code>approval_required</code> at this time</p>
10172
10196
  <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>
10173
10197
  </div>
10174
10198
  <div class="admonition important">
10175
- <p class="admonition-title">Important</p>
10176
- <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>
10199
+ <p class="admonition-title">No recursive JobHookReceivers</p>
10200
+ <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>
10177
10201
  </div>
10178
10202
  <h3 id="example-job-hook-receiver">Example Job Hook Receiver<a class="headerlink" href="#example-job-hook-receiver" title="Permanent link">&para;</a></h3>
10179
10203
  <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>