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

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

Potentially problematic release.


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

Files changed (376) hide show
  1. nautobot/circuits/navigation.py +0 -25
  2. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -9
  3. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
  4. nautobot/circuits/tests/test_filters.py +1 -0
  5. nautobot/core/api/serializers.py +15 -5
  6. nautobot/core/api/views.py +18 -19
  7. nautobot/core/choices.py +1 -1
  8. nautobot/core/filters.py +12 -4
  9. nautobot/core/jobs/__init__.py +125 -3
  10. nautobot/core/management/commands/generate_test_data.py +4 -1
  11. nautobot/core/models/fields.py +12 -2
  12. nautobot/core/settings.py +8 -7
  13. nautobot/core/templates/base_django.html +2 -2
  14. nautobot/core/templates/buttons/export.html +57 -30
  15. nautobot/core/templates/generic/object_list.html +2 -2
  16. nautobot/core/templates/generic/object_retrieve.html +8 -1
  17. nautobot/core/templates/home.html +5 -5
  18. nautobot/core/templates/inc/created_updated.html +2 -2
  19. nautobot/core/templates/inc/footer.html +2 -2
  20. nautobot/core/templates/inc/javascript.html +0 -10
  21. nautobot/core/templates/inc/media.html +2 -0
  22. nautobot/core/templates/inc/nav_menu.html +66 -68
  23. nautobot/core/templates/inc/object_details_advanced_panel.html +19 -0
  24. nautobot/core/templates/nautobot_config.py.j2 +10 -4
  25. nautobot/core/templates/panel_table.html +1 -1
  26. nautobot/core/templates/template.css +89 -0
  27. nautobot/core/templates/utilities/templatetags/table_config_form.html +1 -0
  28. nautobot/core/templatetags/buttons.py +7 -2
  29. nautobot/core/testing/views.py +34 -4
  30. nautobot/core/tests/integration/test_home.py +1 -43
  31. nautobot/core/tests/integration/test_navbar.py +10 -64
  32. nautobot/core/tests/integration/test_plugin_home.py +4 -5
  33. nautobot/core/tests/integration/test_plugin_navbar.py +20 -16
  34. nautobot/core/tests/integration/test_theme.py +4 -0
  35. nautobot/core/tests/test_api.py +14 -66
  36. nautobot/core/tests/test_filters.py +127 -0
  37. nautobot/core/tests/test_forms.py +1 -1
  38. nautobot/core/tests/test_graphql.py +165 -2
  39. nautobot/core/tests/test_jobs.py +112 -0
  40. nautobot/core/tests/test_openapi.py +6 -0
  41. nautobot/core/tests/test_views.py +11 -85
  42. nautobot/core/urls.py +6 -1
  43. nautobot/core/utils/lookup.py +28 -0
  44. nautobot/core/utils/requests.py +2 -3
  45. nautobot/core/views/__init__.py +3 -4
  46. nautobot/core/views/generic.py +9 -4
  47. nautobot/core/views/mixins.py +4 -2
  48. nautobot/core/views/renderers.py +5 -0
  49. nautobot/dcim/models/device_components.py +1 -0
  50. nautobot/dcim/navigation.py +10 -165
  51. nautobot/dcim/templates/dcim/location.html +1 -1
  52. nautobot/dcim/tests/features/locations.feature +143 -0
  53. nautobot/dcim/tests/test_api.py +1 -1
  54. nautobot/dcim/tests/test_filters.py +11 -3
  55. nautobot/extras/admin.py +1 -1
  56. nautobot/extras/api/serializers.py +33 -0
  57. nautobot/extras/api/urls.py +6 -0
  58. nautobot/extras/api/views.py +45 -6
  59. nautobot/extras/factory.py +28 -2
  60. nautobot/extras/filters/__init__.py +52 -0
  61. nautobot/extras/filters/mixins.py +4 -29
  62. nautobot/extras/forms/forms.py +43 -0
  63. nautobot/extras/jobs.py +31 -9
  64. nautobot/extras/migrations/0100_fileproxy_job_result.py +32 -0
  65. nautobot/extras/migrations/0101_externalintegration.py +61 -0
  66. nautobot/extras/migrations/0102_set_null_objectchange_contenttype.py +32 -0
  67. nautobot/extras/models/__init__.py +2 -0
  68. nautobot/extras/models/change_logging.py +2 -2
  69. nautobot/extras/models/models.py +96 -16
  70. nautobot/extras/navigation.py +17 -29
  71. nautobot/extras/signals.py +15 -0
  72. nautobot/extras/tables.py +27 -0
  73. nautobot/extras/templates/extras/externalintegration_retrieve.html +37 -0
  74. nautobot/extras/templates/extras/inc/jobresult.html +24 -0
  75. nautobot/extras/templates/extras/jobresult.html +24 -0
  76. nautobot/extras/test_jobs/file_output.py +16 -0
  77. nautobot/extras/tests/test_api.py +92 -0
  78. nautobot/extras/tests/test_filters.py +64 -2
  79. nautobot/extras/tests/test_jobs.py +39 -0
  80. nautobot/extras/tests/test_models.py +34 -0
  81. nautobot/extras/tests/test_views.py +22 -2
  82. nautobot/extras/urls.py +1 -0
  83. nautobot/extras/views.py +15 -0
  84. nautobot/ipam/forms.py +16 -0
  85. nautobot/ipam/models.py +3 -0
  86. nautobot/ipam/navigation.py +2 -59
  87. nautobot/ipam/templates/ipam/ipaddress.html +0 -9
  88. nautobot/ipam/templates/ipam/prefix.html +0 -9
  89. nautobot/ipam/tests/features/prefixes.feature +134 -0
  90. nautobot/ipam/tests/test_filters.py +5 -10
  91. nautobot/ipam/tests/test_views.py +8 -1
  92. nautobot/ipam/views.py +3 -0
  93. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +191 -191
  94. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  95. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
  96. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  97. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +874 -881
  98. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  99. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  100. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  101. nautobot/project-static/css/base.css +135 -99
  102. nautobot/project-static/css/dark.css +65 -6
  103. nautobot/project-static/docs/404.html +44 -16
  104. nautobot/project-static/docs/apps/index.html +44 -16
  105. nautobot/project-static/docs/apps/nautobot-apps.html +44 -16
  106. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +44 -16
  107. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +44 -16
  108. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1597 -1457
  109. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +44 -16
  110. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +45 -17
  111. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +44 -16
  112. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +44 -16
  113. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +44 -16
  114. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +44 -16
  115. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +353 -432
  116. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +66 -38
  117. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +44 -16
  118. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2154 -2307
  119. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +807 -691
  120. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +44 -16
  121. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +44 -16
  122. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +58 -30
  123. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3600 -3456
  124. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +44 -16
  125. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +44 -16
  126. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +101 -75
  127. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3083 -3019
  128. nautobot/project-static/docs/development/apps/api/configuration-view.html +44 -16
  129. nautobot/project-static/docs/development/apps/api/database-backend-config.html +44 -16
  130. nautobot/project-static/docs/development/apps/api/models/django-admin.html +44 -16
  131. nautobot/project-static/docs/development/apps/api/models/global-search.html +44 -16
  132. nautobot/project-static/docs/development/apps/api/models/graphql.html +44 -16
  133. nautobot/project-static/docs/development/apps/api/models/index.html +44 -16
  134. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +44 -16
  135. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +44 -16
  136. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +44 -16
  137. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +44 -16
  138. nautobot/project-static/docs/development/apps/api/platform-features/index.html +44 -16
  139. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +44 -16
  140. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +44 -16
  141. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +44 -16
  142. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +44 -16
  143. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +44 -16
  144. nautobot/project-static/docs/development/apps/api/prometheus.html +44 -16
  145. nautobot/project-static/docs/development/apps/api/setup.html +44 -16
  146. nautobot/project-static/docs/development/apps/api/testing.html +44 -16
  147. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +44 -16
  148. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +44 -16
  149. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +44 -16
  150. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +44 -16
  151. nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +44 -16
  152. nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +44 -16
  153. nautobot/project-static/docs/development/apps/api/views/base-template.html +44 -16
  154. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +44 -16
  155. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +44 -16
  156. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +44 -16
  157. nautobot/project-static/docs/development/apps/api/views/index.html +44 -16
  158. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +44 -16
  159. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +44 -16
  160. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +44 -16
  161. nautobot/project-static/docs/development/apps/api/views/notes.html +44 -16
  162. nautobot/project-static/docs/development/apps/api/views/rest-api.html +44 -16
  163. nautobot/project-static/docs/development/apps/api/views/urls.html +44 -16
  164. nautobot/project-static/docs/development/apps/api/views/view-overrides.html +44 -16
  165. nautobot/project-static/docs/development/apps/index.html +44 -16
  166. nautobot/project-static/docs/development/apps/migration/code-updates.html +44 -16
  167. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +44 -16
  168. nautobot/project-static/docs/development/apps/migration/from-v1.html +44 -16
  169. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +44 -16
  170. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +44 -16
  171. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +44 -16
  172. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +44 -16
  173. nautobot/project-static/docs/development/apps/porting-from-netbox.html +44 -16
  174. nautobot/project-static/docs/development/core/application-registry.html +44 -16
  175. nautobot/project-static/docs/development/core/best-practices.html +44 -16
  176. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +44 -16
  177. nautobot/project-static/docs/development/core/extending-models.html +44 -16
  178. nautobot/project-static/docs/development/core/generic-views.html +44 -16
  179. nautobot/project-static/docs/development/core/getting-started.html +44 -16
  180. nautobot/project-static/docs/development/core/homepage.html +44 -16
  181. nautobot/project-static/docs/development/core/index.html +44 -16
  182. nautobot/project-static/docs/development/core/model-features.html +44 -16
  183. nautobot/project-static/docs/development/core/natural-keys.html +44 -16
  184. nautobot/project-static/docs/development/core/navigation-menu.html +44 -21
  185. nautobot/project-static/docs/development/core/react-ui.html +44 -16
  186. nautobot/project-static/docs/development/core/release-checklist.html +44 -16
  187. nautobot/project-static/docs/development/core/role-internals.html +44 -16
  188. nautobot/project-static/docs/development/core/style-guide.html +44 -16
  189. nautobot/project-static/docs/development/core/templates.html +44 -16
  190. nautobot/project-static/docs/development/core/testing.html +44 -16
  191. nautobot/project-static/docs/development/core/user-preferences.html +44 -16
  192. nautobot/project-static/docs/development/index.html +44 -16
  193. nautobot/project-static/docs/development/jobs/index.html +280 -234
  194. nautobot/project-static/docs/development/jobs/migration/from-v1.html +44 -16
  195. nautobot/project-static/docs/index.html +44 -16
  196. nautobot/project-static/docs/objects.inv +0 -0
  197. nautobot/project-static/docs/release-notes/index.html +47 -19
  198. nautobot/project-static/docs/release-notes/version-1.0.html +44 -16
  199. nautobot/project-static/docs/release-notes/version-1.1.html +44 -16
  200. nautobot/project-static/docs/release-notes/version-1.2.html +44 -16
  201. nautobot/project-static/docs/release-notes/version-1.3.html +44 -16
  202. nautobot/project-static/docs/release-notes/version-1.4.html +44 -16
  203. nautobot/project-static/docs/release-notes/version-1.5.html +44 -16
  204. nautobot/project-static/docs/release-notes/version-1.6.html +44 -16
  205. nautobot/project-static/docs/release-notes/version-2.0.html +47 -19
  206. nautobot/project-static/docs/release-notes/version-2.1.html +5724 -0
  207. nautobot/project-static/docs/search/search_index.json +1 -1
  208. nautobot/project-static/docs/sitemap.xml +247 -237
  209. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  210. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +44 -16
  211. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +44 -16
  212. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +44 -16
  213. nautobot/project-static/docs/user-guide/administration/configuration/index.html +44 -16
  214. nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +44 -16
  215. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +109 -43
  216. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +44 -16
  217. nautobot/project-static/docs/user-guide/administration/guides/caching.html +44 -16
  218. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +44 -16
  219. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +44 -16
  220. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +44 -16
  221. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +44 -16
  222. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +44 -16
  223. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +48 -19
  224. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +44 -16
  225. nautobot/project-static/docs/user-guide/administration/installation/docker.html +44 -16
  226. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +44 -16
  227. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +44 -16
  228. nautobot/project-static/docs/user-guide/administration/installation/index.html +44 -16
  229. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +44 -16
  230. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +44 -16
  231. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +44 -16
  232. nautobot/project-static/docs/user-guide/administration/installation/services.html +44 -16
  233. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +44 -16
  234. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +44 -16
  235. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +44 -16
  236. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +44 -16
  237. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +44 -16
  238. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +44 -16
  239. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +44 -16
  240. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +44 -16
  241. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +44 -16
  242. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +44 -16
  243. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +44 -16
  244. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +44 -16
  245. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +44 -16
  246. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +44 -16
  247. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +44 -16
  248. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +44 -16
  249. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +44 -16
  250. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +44 -16
  251. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +44 -16
  252. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +44 -16
  253. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +44 -16
  254. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +44 -16
  255. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +44 -16
  256. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +44 -16
  257. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +44 -16
  258. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +44 -16
  259. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +44 -16
  260. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +44 -16
  261. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +44 -16
  262. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +44 -16
  263. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +44 -16
  264. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +44 -16
  265. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +44 -16
  266. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +44 -16
  267. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +44 -16
  268. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +44 -16
  269. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +44 -16
  270. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +44 -16
  271. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +44 -16
  272. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +44 -16
  273. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +44 -16
  274. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +44 -16
  275. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +44 -16
  276. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +44 -16
  277. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +44 -16
  278. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +44 -16
  279. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +44 -16
  280. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +44 -16
  281. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +44 -16
  282. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +44 -16
  283. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +44 -16
  284. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +44 -16
  285. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +44 -16
  286. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +44 -16
  287. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +44 -16
  288. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +44 -16
  289. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +44 -16
  290. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +44 -16
  291. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +44 -16
  292. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +44 -16
  293. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +44 -16
  294. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +44 -16
  295. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +44 -16
  296. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +44 -16
  297. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +44 -16
  298. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +44 -16
  299. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +44 -16
  300. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +44 -16
  301. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +44 -16
  302. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +44 -16
  303. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +44 -16
  304. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +44 -16
  305. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +44 -16
  306. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +44 -16
  307. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +44 -16
  308. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +44 -16
  309. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +44 -16
  310. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +44 -16
  311. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +44 -16
  312. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +44 -16
  313. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +44 -16
  314. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +44 -16
  315. nautobot/project-static/docs/user-guide/index.html +44 -16
  316. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +110 -16
  317. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +44 -16
  318. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +44 -16
  319. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +44 -16
  320. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +44 -16
  321. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +47 -19
  322. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +5359 -0
  323. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +47 -19
  324. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +44 -16
  325. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +44 -16
  326. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +44 -16
  327. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +44 -16
  328. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +44 -16
  329. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +44 -16
  330. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +44 -16
  331. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +44 -16
  332. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +44 -16
  333. nautobot/project-static/docs/user-guide/platform-functionality/note.html +44 -16
  334. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +44 -16
  335. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +44 -16
  336. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +113 -44
  337. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +44 -16
  338. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +44 -16
  339. nautobot/project-static/docs/user-guide/platform-functionality/role.html +44 -16
  340. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +44 -16
  341. nautobot/project-static/docs/user-guide/platform-functionality/status.html +44 -16
  342. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +44 -16
  343. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +44 -16
  344. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +44 -16
  345. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +44 -16
  346. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +44 -16
  347. nautobot/project-static/fonts/UFL.txt +96 -0
  348. nautobot/project-static/fonts/Ubuntu-Bold.woff2 +0 -0
  349. nautobot/project-static/fonts/Ubuntu-BoldItalic.woff2 +0 -0
  350. nautobot/project-static/fonts/Ubuntu-Italic.woff2 +0 -0
  351. nautobot/project-static/fonts/Ubuntu-Medium.woff2 +0 -0
  352. nautobot/project-static/fonts/Ubuntu-MediumItalic.woff2 +0 -0
  353. nautobot/project-static/fonts/Ubuntu-Regular.woff2 +0 -0
  354. nautobot/project-static/fonts/UbuntuMono-Bold.woff2 +0 -0
  355. nautobot/project-static/fonts/UbuntuMono-BoldItalic.woff2 +0 -0
  356. nautobot/project-static/fonts/UbuntuMono-Italic.woff2 +0 -0
  357. nautobot/project-static/fonts/UbuntuMono-Regular.woff2 +0 -0
  358. nautobot/project-static/img/dark-theme.png +0 -0
  359. nautobot/project-static/img/light-theme.png +0 -0
  360. nautobot/project-static/img/nautobot_chevron.svg +5 -0
  361. nautobot/project-static/img/nautobot_chevron_header.svg +5 -0
  362. nautobot/project-static/img/system-theme.png +0 -0
  363. nautobot/tenancy/navigation.py +0 -13
  364. nautobot/ui/package-lock.json +2 -2
  365. nautobot/ui/package.json +1 -1
  366. nautobot/users/admin.py +44 -0
  367. nautobot/users/migrations/0007_alter_objectpermission_object_types.py +33 -0
  368. nautobot/users/models.py +3 -2
  369. nautobot/virtualization/navigation.py +1 -33
  370. nautobot/virtualization/tests/test_api.py +1 -1
  371. nautobot/virtualization/tests/test_filters.py +1 -1
  372. {nautobot-2.0.5.dist-info → nautobot-2.1.0b1.dist-info}/METADATA +1 -1
  373. {nautobot-2.0.5.dist-info → nautobot-2.1.0b1.dist-info}/RECORD +376 -351
  374. {nautobot-2.0.5.dist-info → nautobot-2.1.0b1.dist-info}/LICENSE.txt +0 -0
  375. {nautobot-2.0.5.dist-info → nautobot-2.1.0b1.dist-info}/WHEEL +0 -0
  376. {nautobot-2.0.5.dist-info → nautobot-2.1.0b1.dist-info}/entry_points.txt +0 -0
@@ -2659,6 +2659,20 @@
2659
2659
 
2660
2660
 
2661
2661
 
2662
+ <li class="md-nav__item">
2663
+ <a href="../../user-guide/platform-functionality/externalintegration.html" class="md-nav__link">
2664
+ External Integrations
2665
+ </a>
2666
+ </li>
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2662
2676
  <li class="md-nav__item">
2663
2677
  <a href="../../user-guide/platform-functionality/gitrepository.html" class="md-nav__link">
2664
2678
  Git Repositories
@@ -2679,7 +2693,7 @@
2679
2693
 
2680
2694
 
2681
2695
 
2682
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_8" >
2696
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_9" >
2683
2697
 
2684
2698
 
2685
2699
 
@@ -2688,14 +2702,14 @@
2688
2702
  <div class="md-nav__link md-nav__link--index ">
2689
2703
  <a href="../../user-guide/platform-functionality/graphql.html">GraphQL</a>
2690
2704
 
2691
- <label for="__nav_2_4_8">
2705
+ <label for="__nav_2_4_9">
2692
2706
  <span class="md-nav__icon md-icon"></span>
2693
2707
  </label>
2694
2708
 
2695
2709
  </div>
2696
2710
 
2697
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_8_label" aria-expanded="false">
2698
- <label class="md-nav__title" for="__nav_2_4_8">
2711
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_9_label" aria-expanded="false">
2712
+ <label class="md-nav__title" for="__nav_2_4_9">
2699
2713
  <span class="md-nav__icon md-icon"></span>
2700
2714
  GraphQL
2701
2715
  </label>
@@ -2747,7 +2761,7 @@
2747
2761
 
2748
2762
 
2749
2763
 
2750
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_10" >
2764
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_11" >
2751
2765
 
2752
2766
 
2753
2767
 
@@ -2756,14 +2770,14 @@
2756
2770
  <div class="md-nav__link md-nav__link--index ">
2757
2771
  <a href="../../user-guide/platform-functionality/jobs/index.html">Jobs</a>
2758
2772
 
2759
- <label for="__nav_2_4_10">
2773
+ <label for="__nav_2_4_11">
2760
2774
  <span class="md-nav__icon md-icon"></span>
2761
2775
  </label>
2762
2776
 
2763
2777
  </div>
2764
2778
 
2765
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_10_label" aria-expanded="false">
2766
- <label class="md-nav__title" for="__nav_2_4_10">
2779
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_11_label" aria-expanded="false">
2780
+ <label class="md-nav__title" for="__nav_2_4_11">
2767
2781
  <span class="md-nav__icon md-icon"></span>
2768
2782
  Jobs
2769
2783
  </label>
@@ -2885,7 +2899,7 @@
2885
2899
 
2886
2900
 
2887
2901
 
2888
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_14" >
2902
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_15" >
2889
2903
 
2890
2904
 
2891
2905
 
@@ -2894,14 +2908,14 @@
2894
2908
  <div class="md-nav__link md-nav__link--index ">
2895
2909
  <a href="../../user-guide/platform-functionality/rest-api/overview.html">REST API</a>
2896
2910
 
2897
- <label for="__nav_2_4_14">
2911
+ <label for="__nav_2_4_15">
2898
2912
  <span class="md-nav__icon md-icon"></span>
2899
2913
  </label>
2900
2914
 
2901
2915
  </div>
2902
2916
 
2903
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_14_label" aria-expanded="false">
2904
- <label class="md-nav__title" for="__nav_2_4_14">
2917
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_15_label" aria-expanded="false">
2918
+ <label class="md-nav__title" for="__nav_2_4_15">
2905
2919
  <span class="md-nav__icon md-icon"></span>
2906
2920
  REST API
2907
2921
  </label>
@@ -3037,17 +3051,17 @@
3037
3051
 
3038
3052
 
3039
3053
 
3040
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_20" >
3054
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_21" >
3041
3055
 
3042
3056
 
3043
3057
 
3044
- <label class="md-nav__link" for="__nav_2_4_20" id="__nav_2_4_20_label" tabindex="0">
3058
+ <label class="md-nav__link" for="__nav_2_4_21" id="__nav_2_4_21_label" tabindex="0">
3045
3059
  Users
3046
3060
  <span class="md-nav__icon md-icon"></span>
3047
3061
  </label>
3048
3062
 
3049
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_20_label" aria-expanded="false">
3050
- <label class="md-nav__title" for="__nav_2_4_20">
3063
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_21_label" aria-expanded="false">
3064
+ <label class="md-nav__title" for="__nav_2_4_21">
3051
3065
  <span class="md-nav__icon md-icon"></span>
3052
3066
  Users
3053
3067
  </label>
@@ -4784,6 +4798,20 @@
4784
4798
 
4785
4799
 
4786
4800
 
4801
+ <li class="md-nav__item">
4802
+ <a href="../../release-notes/version-2.1.html" class="md-nav__link">
4803
+ Version 2.1
4804
+ </a>
4805
+ </li>
4806
+
4807
+
4808
+
4809
+
4810
+
4811
+
4812
+
4813
+
4814
+
4787
4815
  <li class="md-nav__item">
4788
4816
  <a href="../../release-notes/version-2.0.html" class="md-nav__link">
4789
4817
  Version 2.0
@@ -5408,6 +5436,13 @@
5408
5436
  Logging
5409
5437
  </a>
5410
5438
 
5439
+ </li>
5440
+
5441
+ <li class="md-nav__item">
5442
+ <a href="#file-output" class="md-nav__link">
5443
+ File Output
5444
+ </a>
5445
+
5411
5446
  </li>
5412
5447
 
5413
5448
  <li class="md-nav__item">
@@ -5961,20 +5996,31 @@ default <a href="../../user-guide/administration/configuration/optional-settings
5961
5996
  <p class="admonition-title">Changed in version 2.0.0</p>
5962
5997
  <p>The <code>AbortTransaction</code> class was moved from the <code>nautobot.utilities.exceptions</code> module to <code>nautobot.core.exceptions</code>.</p>
5963
5998
  </div>
5999
+ <h3 id="file-output">File Output<a class="headerlink" href="#file-output" title="Permanent link">&para;</a></h3>
6000
+ <div class="admonition version-added">
6001
+ <p class="admonition-title">Added in version 2.1.0</p>
6002
+ </div>
6003
+ <p>A Job can create files that will be saved and can later be downloaded by a user. (The specifics of how and where these files are stored will depend on your system's <a href="../../user-guide/administration/configuration/optional-settings.html#job_file_io_storage"><code>JOB_FILE_IO_STORAGE</code></a> configuration.) To do so, use the <code>Job.create_file(filename, content)</code> method:</p>
6004
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="kn">from</span> <span class="nn">nautobot.extras.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
6005
+ <a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>
6006
+ <a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-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>
6007
+ <a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6008
+ <a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a> <span class="bp">self</span><span class="o">.</span><span class="n">create_file</span><span class="p">(</span><span class="s2">&quot;greeting.txt&quot;</span><span class="p">,</span> <span class="s2">&quot;Hello world!&quot;</span><span class="p">)</span>
6009
+ <a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">create_file</span><span class="p">(</span><span class="s2">&quot;farewell.txt&quot;</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;Goodbye for now!&quot;</span><span class="p">)</span> <span class="c1"># content can be a str or bytes</span>
6010
+ </code></pre></div>
6011
+ <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 "Additional Data" 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>
5964
6012
  <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>
5965
6013
  <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>
5966
- <div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="n">As</span> <span class="n">an</span> <span class="n">example</span><span class="p">,</span> <span class="n">the</span> <span class="n">following</span> <span class="n">job</span> <span class="n">will</span> <span class="n">fail</span> <span class="k">if</span> <span class="n">the</span> <span class="n">user</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">put</span> <span class="n">the</span> <span class="n">word</span> <span class="s2">&quot;Taco&quot;</span> <span class="ow">in</span> <span class="err">`</span><span class="n">var1</span><span class="err">`</span><span class="p">:</span>
5967
- <a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>
5968
- <a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="err">```</span><span class="n">python</span>
5969
- <a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></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>
5970
- <a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a>
5971
- <a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
5972
- <a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a> <span class="n">var1</span> <span class="o">=</span> <span class="n">StringVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
5973
- <a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a>
5974
- <a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></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="n">var1</span><span class="p">):</span>
5975
- <a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a> <span class="k">if</span> <span class="n">var1</span> <span class="o">!=</span> <span class="s2">&quot;Taco&quot;</span><span class="p">:</span>
5976
- <a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;var1 must be &#39;Taco&#39;&quot;</span><span class="p">)</span>
5977
- <a id="__codelineno-14-12" name="__codelineno-14-12" href="#__codelineno-14-12"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Argument input validation failed.&quot;</span><span class="p">)</span>
6014
+ <p>As an example, the following job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
6015
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-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>
6016
+ <a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>
6017
+ <a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-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>
6018
+ <a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a> <span class="n">var1</span> <span class="o">=</span> <span class="n">StringVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
6019
+ <a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a>
6020
+ <a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></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="n">var1</span><span class="p">):</span>
6021
+ <a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a> <span class="k">if</span> <span class="n">var1</span> <span class="o">!=</span> <span class="s2">&quot;Taco&quot;</span><span class="p">:</span>
6022
+ <a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;var1 must be &#39;Taco&#39;&quot;</span><span class="p">)</span>
6023
+ <a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Argument input validation failed.&quot;</span><span class="p">)</span>
5978
6024
  </code></pre></div>
5979
6025
  <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>
5980
6026
  <div class="admonition version-changed">
@@ -5982,9 +6028,9 @@ default <a href="../../user-guide/administration/configuration/optional-settings
5982
6028
  <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>
5983
6029
  </div>
5984
6030
  <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>
5985
- <div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-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>
5986
- <a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-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>
5987
- <a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-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>
6031
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-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>
6032
+ <a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-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>
6033
+ <a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-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>
5988
6034
  </code></pre></div>
5989
6035
  <h3 id="reading-data-from-files">Reading Data from Files<a class="headerlink" href="#reading-data-from-files" title="Permanent link">&para;</a></h3>
5990
6036
  <p>The <code>Job</code> class provides two convenience methods for reading data from files:</p>
@@ -6005,21 +6051,21 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
6005
6051
  <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>
6006
6052
  <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>
6007
6053
  <p>A simple example of a Job test case might look like the following:</p>
6008
- <div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-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>
6009
- <a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-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>
6010
- <a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a>
6011
- <a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a>
6012
- <a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a><span class="k">class</span> <span class="nc">MyJobTestCase</span><span class="p">(</span><span class="n">TransactionTestCase</span><span class="p">):</span>
6013
- <a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a> <span class="k">def</span> <span class="nf">test_my_job</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6014
- <a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a> <span class="c1"># Testing of Job &quot;MyJob&quot; in file &quot;my_job_file.py&quot; in $JOBS_ROOT</span>
6015
- <a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a> <span class="n">job</span> <span class="o">=</span> <span class="n">Job</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">job_class_name</span><span class="o">=</span><span class="s2">&quot;MyJob&quot;</span><span class="p">,</span> <span class="n">module_name</span><span class="o">=</span><span class="s2">&quot;my_job_file&quot;</span><span class="p">,</span> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;local&quot;</span><span class="p">)</span>
6016
- <a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a> <span class="c1"># or, job = Job.objects.get_for_class_path(&quot;local/my_job_file/MyJob&quot;)</span>
6017
- <a id="__codelineno-16-10" name="__codelineno-16-10" href="#__codelineno-16-10"></a> <span class="n">job_result</span> <span class="o">=</span> <span class="n">run_job_for_testing</span><span class="p">(</span><span class="n">job</span><span class="p">,</span> <span class="n">var1</span><span class="o">=</span><span class="s2">&quot;abc&quot;</span><span class="p">,</span> <span class="n">var2</span><span class="o">=</span><span class="mi">123</span><span class="p">)</span>
6018
- <a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a>
6019
- <a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a> <span class="c1"># Inspect the logs created by running the job</span>
6020
- <a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a> <span class="n">log_entries</span> <span class="o">=</span> <span class="n">JobLogEntry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">job_result</span><span class="o">=</span><span class="n">job_result</span><span class="p">)</span>
6021
- <a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a> <span class="k">for</span> <span class="n">log_entry</span> <span class="ow">in</span> <span class="n">log_entries</span><span class="p">:</span>
6022
- <a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a> <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">log_entry</span><span class="o">.</span><span class="n">message</span><span class="p">,</span> <span class="s2">&quot;...&quot;</span><span class="p">)</span>
6054
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-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>
6055
+ <a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-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>
6056
+ <a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a>
6057
+ <a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a>
6058
+ <a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="k">class</span> <span class="nc">MyJobTestCase</span><span class="p">(</span><span class="n">TransactionTestCase</span><span class="p">):</span>
6059
+ <a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a> <span class="k">def</span> <span class="nf">test_my_job</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6060
+ <a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a> <span class="c1"># Testing of Job &quot;MyJob&quot; in file &quot;my_job_file.py&quot; in $JOBS_ROOT</span>
6061
+ <a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a> <span class="n">job</span> <span class="o">=</span> <span class="n">Job</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">job_class_name</span><span class="o">=</span><span class="s2">&quot;MyJob&quot;</span><span class="p">,</span> <span class="n">module_name</span><span class="o">=</span><span class="s2">&quot;my_job_file&quot;</span><span class="p">,</span> <span class="n">source</span><span class="o">=</span><span class="s2">&quot;local&quot;</span><span class="p">)</span>
6062
+ <a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a> <span class="c1"># or, job = Job.objects.get_for_class_path(&quot;local/my_job_file/MyJob&quot;)</span>
6063
+ <a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a> <span class="n">job_result</span> <span class="o">=</span> <span class="n">run_job_for_testing</span><span class="p">(</span><span class="n">job</span><span class="p">,</span> <span class="n">var1</span><span class="o">=</span><span class="s2">&quot;abc&quot;</span><span class="p">,</span> <span class="n">var2</span><span class="o">=</span><span class="mi">123</span><span class="p">)</span>
6064
+ <a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a>
6065
+ <a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a> <span class="c1"># Inspect the logs created by running the job</span>
6066
+ <a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a> <span class="n">log_entries</span> <span class="o">=</span> <span class="n">JobLogEntry</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">job_result</span><span class="o">=</span><span class="n">job_result</span><span class="p">)</span>
6067
+ <a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a> <span class="k">for</span> <span class="n">log_entry</span> <span class="ow">in</span> <span class="n">log_entries</span><span class="p">:</span>
6068
+ <a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a> <span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">log_entry</span><span class="o">.</span><span class="n">message</span><span class="p">,</span> <span class="s2">&quot;...&quot;</span><span class="p">)</span>
6023
6069
  </code></pre></div>
6024
6070
  <div class="admonition tip">
6025
6071
  <p class="admonition-title">Tip</p>
@@ -6037,10 +6083,10 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
6037
6083
  </div>
6038
6084
  <h3 id="reading-profiling-reports">Reading profiling reports<a class="headerlink" href="#reading-profiling-reports" title="Permanent link">&para;</a></h3>
6039
6085
  <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>
6040
- <div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="kn">import</span> <span class="nn">pstats</span>
6041
- <a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="n">job_result_uuid</span> <span class="o">=</span> <span class="s2">&quot;66b70231-002f-412b-8cc4-1cc9609c2c9b&quot;</span>
6042
- <a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-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/job-result-</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>
6043
- <a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-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>
6086
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kn">import</span> <span class="nn">pstats</span>
6087
+ <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="n">job_result_uuid</span> <span class="o">=</span> <span class="s2">&quot;66b70231-002f-412b-8cc4-1cc9609c2c9b&quot;</span>
6088
+ <a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-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/job-result-</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>
6089
+ <a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-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>
6044
6090
  </code></pre></div>
6045
6091
  <p>This will print the 10 functions that the job execution spent the most time in - adapt this to your needs!</p>
6046
6092
  <h2 id="example-jobs">Example Jobs<a class="headerlink" href="#example-jobs" title="Permanent link">&para;</a></h2>
@@ -6052,119 +6098,119 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
6052
6098
  <li>The number of access switches to create</li>
6053
6099
  </ul>
6054
6100
  <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>
6055
- <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">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span>
6056
- <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>
6057
- <a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-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>
6058
- <a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Location</span><span class="p">,</span> <span class="n">LocationType</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Manufacturer</span><span class="p">,</span> <span class="n">DeviceType</span>
6059
- <a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Role</span>
6060
- <a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a>
6061
- <a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a>
6062
- <a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a><span class="k">class</span> <span class="nc">NewBranch</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
6063
- <a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6064
- <a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;New Branch&quot;</span>
6065
- <a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Provision a new branch location&quot;</span>
6066
- <a id="__codelineno-18-12" name="__codelineno-18-12" href="#__codelineno-18-12"></a> <span class="n">field_order</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;location_name&quot;</span><span class="p">,</span> <span class="s2">&quot;switch_count&quot;</span><span class="p">,</span> <span class="s2">&quot;switch_model&quot;</span><span class="p">]</span>
6067
- <a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a>
6068
- <a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a> <span class="n">location_name</span> <span class="o">=</span> <span class="n">StringVar</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Name of the new location&quot;</span><span class="p">)</span>
6069
- <a id="__codelineno-18-15" name="__codelineno-18-15" href="#__codelineno-18-15"></a> <span class="n">switch_count</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Number of access switches to create&quot;</span><span class="p">)</span>
6070
- <a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a> <span class="n">manufacturer</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="n">Manufacturer</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
6071
- <a id="__codelineno-18-17" name="__codelineno-18-17" href="#__codelineno-18-17"></a> <span class="n">switch_model</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
6072
- <a id="__codelineno-18-18" name="__codelineno-18-18" href="#__codelineno-18-18"></a> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Access switch model&quot;</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">DeviceType</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;manufacturer_id&quot;</span><span class="p">:</span> <span class="s2">&quot;$manufacturer&quot;</span><span class="p">}</span>
6073
- <a id="__codelineno-18-19" name="__codelineno-18-19" href="#__codelineno-18-19"></a> <span class="p">)</span>
6074
- <a id="__codelineno-18-20" name="__codelineno-18-20" href="#__codelineno-18-20"></a>
6075
- <a id="__codelineno-18-21" name="__codelineno-18-21" href="#__codelineno-18-21"></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="n">location_name</span><span class="p">,</span> <span class="n">switch_count</span><span class="p">,</span> <span class="n">switch_model</span><span class="p">):</span>
6076
- <a id="__codelineno-18-22" name="__codelineno-18-22" href="#__codelineno-18-22"></a> <span class="n">STATUS_PLANNED</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Planned&quot;</span><span class="p">)</span>
6077
- <a id="__codelineno-18-23" name="__codelineno-18-23" href="#__codelineno-18-23"></a>
6078
- <a id="__codelineno-18-24" name="__codelineno-18-24" href="#__codelineno-18-24"></a> <span class="c1"># Create the new location</span>
6079
- <a id="__codelineno-18-25" name="__codelineno-18-25" href="#__codelineno-18-25"></a> <span class="n">root_type</span> <span class="o">=</span> <span class="n">LocationType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Campus&quot;</span><span class="p">)</span>
6080
- <a id="__codelineno-18-26" name="__codelineno-18-26" href="#__codelineno-18-26"></a> <span class="n">location</span> <span class="o">=</span> <span class="n">Location</span><span class="p">(</span>
6081
- <a id="__codelineno-18-27" name="__codelineno-18-27" href="#__codelineno-18-27"></a> <span class="n">name</span><span class="o">=</span><span class="n">location_name</span><span class="p">,</span>
6082
- <a id="__codelineno-18-28" name="__codelineno-18-28" href="#__codelineno-18-28"></a> <span class="n">location_type</span><span class="o">=</span><span class="n">root_type</span><span class="p">,</span>
6083
- <a id="__codelineno-18-29" name="__codelineno-18-29" href="#__codelineno-18-29"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
6084
- <a id="__codelineno-18-30" name="__codelineno-18-30" href="#__codelineno-18-30"></a> <span class="p">)</span>
6085
- <a id="__codelineno-18-31" name="__codelineno-18-31" href="#__codelineno-18-31"></a> <span class="n">location</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
6086
- <a id="__codelineno-18-32" name="__codelineno-18-32" href="#__codelineno-18-32"></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;Created new location&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">location</span><span class="p">})</span>
6087
- <a id="__codelineno-18-33" name="__codelineno-18-33" href="#__codelineno-18-33"></a>
6088
- <a id="__codelineno-18-34" name="__codelineno-18-34" href="#__codelineno-18-34"></a> <span class="c1"># Create access switches</span>
6089
- <a id="__codelineno-18-35" name="__codelineno-18-35" href="#__codelineno-18-35"></a> <span class="n">device_ct</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_for_model</span><span class="p">(</span><span class="n">Device</span><span class="p">)</span>
6090
- <a id="__codelineno-18-36" name="__codelineno-18-36" href="#__codelineno-18-36"></a> <span class="n">switch_role</span> <span class="o">=</span> <span class="n">Role</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Access Switch&quot;</span><span class="p">)</span>
6091
- <a id="__codelineno-18-37" name="__codelineno-18-37" href="#__codelineno-18-37"></a> <span class="n">switch_role</span><span class="o">.</span><span class="n">content_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">device_ct</span><span class="p">)</span>
6092
- <a id="__codelineno-18-38" name="__codelineno-18-38" href="#__codelineno-18-38"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">switch_count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
6093
- <a id="__codelineno-18-39" name="__codelineno-18-39" href="#__codelineno-18-39"></a> <span class="n">switch</span> <span class="o">=</span> <span class="n">Device</span><span class="p">(</span>
6094
- <a id="__codelineno-18-40" name="__codelineno-18-40" href="#__codelineno-18-40"></a> <span class="n">device_type</span><span class="o">=</span><span class="n">switch_model</span><span class="p">,</span>
6095
- <a id="__codelineno-18-41" name="__codelineno-18-41" href="#__codelineno-18-41"></a> <span class="n">name</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">location</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">-switch</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
6096
- <a id="__codelineno-18-42" name="__codelineno-18-42" href="#__codelineno-18-42"></a> <span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">,</span>
6097
- <a id="__codelineno-18-43" name="__codelineno-18-43" href="#__codelineno-18-43"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
6098
- <a id="__codelineno-18-44" name="__codelineno-18-44" href="#__codelineno-18-44"></a> <span class="n">role</span><span class="o">=</span><span class="n">switch_role</span><span class="p">,</span>
6099
- <a id="__codelineno-18-45" name="__codelineno-18-45" href="#__codelineno-18-45"></a> <span class="p">)</span>
6100
- <a id="__codelineno-18-46" name="__codelineno-18-46" href="#__codelineno-18-46"></a> <span class="n">switch</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
6101
- <a id="__codelineno-18-47" name="__codelineno-18-47" href="#__codelineno-18-47"></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;Created new switch&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">switch</span><span class="p">})</span>
6102
- <a id="__codelineno-18-48" name="__codelineno-18-48" href="#__codelineno-18-48"></a>
6103
- <a id="__codelineno-18-49" name="__codelineno-18-49" href="#__codelineno-18-49"></a> <span class="c1"># Generate a CSV table of new devices</span>
6104
- <a id="__codelineno-18-50" name="__codelineno-18-50" href="#__codelineno-18-50"></a> <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;name,make,model&quot;</span><span class="p">]</span>
6105
- <a id="__codelineno-18-51" name="__codelineno-18-51" href="#__codelineno-18-51"></a> <span class="k">for</span> <span class="n">switch</span> <span class="ow">in</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">):</span>
6106
- <a id="__codelineno-18-52" name="__codelineno-18-52" href="#__codelineno-18-52"></a> <span class="n">attrs</span> <span class="o">=</span> <span class="p">[</span><span class="n">switch</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">switch</span><span class="o">.</span><span class="n">device_type</span><span class="o">.</span><span class="n">manufacturer</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">switch</span><span class="o">.</span><span class="n">device_type</span><span class="o">.</span><span class="n">model</span><span class="p">]</span>
6107
- <a id="__codelineno-18-53" name="__codelineno-18-53" href="#__codelineno-18-53"></a> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">attrs</span><span class="p">))</span>
6108
- <a id="__codelineno-18-54" name="__codelineno-18-54" href="#__codelineno-18-54"></a>
6109
- <a id="__codelineno-18-55" name="__codelineno-18-55" href="#__codelineno-18-55"></a> <span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
6101
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-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>
6102
+ <a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>
6103
+ <a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-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>
6104
+ <a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Location</span><span class="p">,</span> <span class="n">LocationType</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Manufacturer</span><span class="p">,</span> <span class="n">DeviceType</span>
6105
+ <a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Role</span>
6106
+ <a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a>
6107
+ <a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a>
6108
+ <a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a><span class="k">class</span> <span class="nc">NewBranch</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
6109
+ <a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6110
+ <a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;New Branch&quot;</span>
6111
+ <a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Provision a new branch location&quot;</span>
6112
+ <a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a> <span class="n">field_order</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;location_name&quot;</span><span class="p">,</span> <span class="s2">&quot;switch_count&quot;</span><span class="p">,</span> <span class="s2">&quot;switch_model&quot;</span><span class="p">]</span>
6113
+ <a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a>
6114
+ <a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a> <span class="n">location_name</span> <span class="o">=</span> <span class="n">StringVar</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Name of the new location&quot;</span><span class="p">)</span>
6115
+ <a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a> <span class="n">switch_count</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Number of access switches to create&quot;</span><span class="p">)</span>
6116
+ <a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a> <span class="n">manufacturer</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="n">Manufacturer</span><span class="p">,</span> <span class="n">required</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
6117
+ <a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a> <span class="n">switch_model</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
6118
+ <a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a> <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Access switch model&quot;</span><span class="p">,</span> <span class="n">model</span><span class="o">=</span><span class="n">DeviceType</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;manufacturer_id&quot;</span><span class="p">:</span> <span class="s2">&quot;$manufacturer&quot;</span><span class="p">}</span>
6119
+ <a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a> <span class="p">)</span>
6120
+ <a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a>
6121
+ <a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></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="n">location_name</span><span class="p">,</span> <span class="n">switch_count</span><span class="p">,</span> <span class="n">switch_model</span><span class="p">):</span>
6122
+ <a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a> <span class="n">STATUS_PLANNED</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Planned&quot;</span><span class="p">)</span>
6123
+ <a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a>
6124
+ <a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a> <span class="c1"># Create the new location</span>
6125
+ <a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a> <span class="n">root_type</span> <span class="o">=</span> <span class="n">LocationType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_or_create</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Campus&quot;</span><span class="p">)</span>
6126
+ <a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a> <span class="n">location</span> <span class="o">=</span> <span class="n">Location</span><span class="p">(</span>
6127
+ <a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a> <span class="n">name</span><span class="o">=</span><span class="n">location_name</span><span class="p">,</span>
6128
+ <a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a> <span class="n">location_type</span><span class="o">=</span><span class="n">root_type</span><span class="p">,</span>
6129
+ <a id="__codelineno-19-29" name="__codelineno-19-29" href="#__codelineno-19-29"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
6130
+ <a id="__codelineno-19-30" name="__codelineno-19-30" href="#__codelineno-19-30"></a> <span class="p">)</span>
6131
+ <a id="__codelineno-19-31" name="__codelineno-19-31" href="#__codelineno-19-31"></a> <span class="n">location</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
6132
+ <a id="__codelineno-19-32" name="__codelineno-19-32" href="#__codelineno-19-32"></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;Created new location&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">location</span><span class="p">})</span>
6133
+ <a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a>
6134
+ <a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a> <span class="c1"># Create access switches</span>
6135
+ <a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a> <span class="n">device_ct</span> <span class="o">=</span> <span class="n">ContentType</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_for_model</span><span class="p">(</span><span class="n">Device</span><span class="p">)</span>
6136
+ <a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a> <span class="n">switch_role</span> <span class="o">=</span> <span class="n">Role</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;Access Switch&quot;</span><span class="p">)</span>
6137
+ <a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a> <span class="n">switch_role</span><span class="o">.</span><span class="n">content_types</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">device_ct</span><span class="p">)</span>
6138
+ <a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">switch_count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
6139
+ <a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a> <span class="n">switch</span> <span class="o">=</span> <span class="n">Device</span><span class="p">(</span>
6140
+ <a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a> <span class="n">device_type</span><span class="o">=</span><span class="n">switch_model</span><span class="p">,</span>
6141
+ <a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a> <span class="n">name</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">location</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">-switch</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span>
6142
+ <a id="__codelineno-19-42" name="__codelineno-19-42" href="#__codelineno-19-42"></a> <span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">,</span>
6143
+ <a id="__codelineno-19-43" name="__codelineno-19-43" href="#__codelineno-19-43"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
6144
+ <a id="__codelineno-19-44" name="__codelineno-19-44" href="#__codelineno-19-44"></a> <span class="n">role</span><span class="o">=</span><span class="n">switch_role</span><span class="p">,</span>
6145
+ <a id="__codelineno-19-45" name="__codelineno-19-45" href="#__codelineno-19-45"></a> <span class="p">)</span>
6146
+ <a id="__codelineno-19-46" name="__codelineno-19-46" href="#__codelineno-19-46"></a> <span class="n">switch</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
6147
+ <a id="__codelineno-19-47" name="__codelineno-19-47" href="#__codelineno-19-47"></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;Created new switch&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">switch</span><span class="p">})</span>
6148
+ <a id="__codelineno-19-48" name="__codelineno-19-48" href="#__codelineno-19-48"></a>
6149
+ <a id="__codelineno-19-49" name="__codelineno-19-49" href="#__codelineno-19-49"></a> <span class="c1"># Generate a CSV table of new devices</span>
6150
+ <a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a> <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;name,make,model&quot;</span><span class="p">]</span>
6151
+ <a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a> <span class="k">for</span> <span class="n">switch</span> <span class="ow">in</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">):</span>
6152
+ <a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a> <span class="n">attrs</span> <span class="o">=</span> <span class="p">[</span><span class="n">switch</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">switch</span><span class="o">.</span><span class="n">device_type</span><span class="o">.</span><span class="n">manufacturer</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">switch</span><span class="o">.</span><span class="n">device_type</span><span class="o">.</span><span class="n">model</span><span class="p">]</span>
6153
+ <a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">attrs</span><span class="p">))</span>
6154
+ <a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a>
6155
+ <a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></a> <span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
6110
6156
  </code></pre></div>
6111
6157
  <h3 id="device-validation">Device validation<a class="headerlink" href="#device-validation" title="Permanent link">&para;</a></h3>
6112
6158
  <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, nor does it implement a <code>run()</code> method.</p>
6113
- <div class="highlight"><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
6114
- <a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-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>
6115
- <a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
6116
- <a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a>
6117
- <a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a>
6118
- <a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-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>
6119
- <a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Validate the minimum physical connections for each device&quot;</span>
6120
- <a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a>
6121
- <a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a> <span class="k">def</span> <span class="nf">test_console_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6122
- <a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a> <span class="n">STATUS_ACTIVE</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;Active&#39;</span><span class="p">)</span>
6123
- <a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a>
6124
- <a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a> <span class="c1"># Check that every console port for every active device has a connection defined.</span>
6125
- <a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a> <span class="k">for</span> <span class="n">console_port</span> <span class="ow">in</span> <span class="n">ConsolePort</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;device&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">device__status</span><span class="o">=</span><span class="n">STATUS_ACTIVE</span><span class="p">):</span>
6126
- <a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a> <span class="k">if</span> <span class="n">console_port</span><span class="o">.</span><span class="n">connected_endpoint</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
6127
- <a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
6128
- <a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a> <span class="s2">&quot;No console connection defined for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span>
6129
- <a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6130
- <a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6131
- <a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a> <span class="p">)</span>
6132
- <a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a> <span class="k">elif</span> <span class="ow">not</span> <span class="n">console_port</span><span class="o">.</span><span class="n">connection_status</span><span class="p">:</span>
6133
- <a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
6134
- <a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a> <span class="s2">&quot;Console connection for </span><span class="si">%s</span><span class="s2"> marked as planned&quot;</span><span class="p">,</span>
6135
- <a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6136
- <a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6137
- <a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a> <span class="p">)</span>
6138
- <a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a> <span class="k">else</span><span class="p">:</span>
6139
- <a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></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>
6140
- <a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a> <span class="s2">&quot;Console port </span><span class="si">%s</span><span class="s2"> has a connection defined&quot;</span><span class="p">,</span>
6141
- <a id="__codelineno-19-29" name="__codelineno-19-29" href="#__codelineno-19-29"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6142
- <a id="__codelineno-19-30" name="__codelineno-19-30" href="#__codelineno-19-30"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6143
- <a id="__codelineno-19-31" name="__codelineno-19-31" href="#__codelineno-19-31"></a> <span class="p">)</span>
6144
- <a id="__codelineno-19-32" name="__codelineno-19-32" href="#__codelineno-19-32"></a>
6145
- <a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a> <span class="k">def</span> <span class="nf">test_power_connections</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6146
- <a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a> <span class="n">STATUS_ACTIVE</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;Active&#39;</span><span class="p">)</span>
6147
- <a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a>
6148
- <a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a> <span class="c1"># Check that every active device has at least two connected power supplies.</span>
6149
- <a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a> <span class="k">for</span> <span class="n">device</span> <span class="ow">in</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="n">STATUS_ACTIVE</span><span class="p">):</span>
6150
- <a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a> <span class="n">connected_ports</span> <span class="o">=</span> <span class="mi">0</span>
6151
- <a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a> <span class="k">for</span> <span class="n">power_port</span> <span class="ow">in</span> <span class="n">PowerPort</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">):</span>
6152
- <a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a> <span class="k">if</span> <span class="n">power_port</span><span class="o">.</span><span class="n">connected_endpoint</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6153
- <a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a> <span class="n">connected_ports</span> <span class="o">+=</span> <span class="mi">1</span>
6154
- <a id="__codelineno-19-42" name="__codelineno-19-42" href="#__codelineno-19-42"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">power_port</span><span class="o">.</span><span class="n">connection_status</span><span class="p">:</span>
6155
- <a id="__codelineno-19-43" name="__codelineno-19-43" href="#__codelineno-19-43"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
6156
- <a id="__codelineno-19-44" name="__codelineno-19-44" href="#__codelineno-19-44"></a> <span class="s2">&quot;Power connection for </span><span class="si">%s</span><span class="s2"> marked as planned&quot;</span><span class="p">,</span>
6157
- <a id="__codelineno-19-45" name="__codelineno-19-45" href="#__codelineno-19-45"></a> <span class="n">power_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6158
- <a id="__codelineno-19-46" name="__codelineno-19-46" href="#__codelineno-19-46"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
6159
- <a id="__codelineno-19-47" name="__codelineno-19-47" href="#__codelineno-19-47"></a> <span class="p">)</span>
6160
- <a id="__codelineno-19-48" name="__codelineno-19-48" href="#__codelineno-19-48"></a> <span class="k">if</span> <span class="n">connected_ports</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
6161
- <a id="__codelineno-19-49" name="__codelineno-19-49" href="#__codelineno-19-49"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
6162
- <a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> connected power supplies found (2 needed)&quot;</span><span class="p">,</span>
6163
- <a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a> <span class="n">connected_ports</span><span class="p">,</span>
6164
- <a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
6165
- <a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a> <span class="p">)</span>
6166
- <a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a> <span class="k">else</span><span class="p">:</span>
6167
- <a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></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;At least two connected power supplies found&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">})</span>
6159
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
6160
+ <a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-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>
6161
+ <a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
6162
+ <a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a>
6163
+ <a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>
6164
+ <a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-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>
6165
+ <a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Validate the minimum physical connections for each device&quot;</span>
6166
+ <a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a>
6167
+ <a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></a> <span class="k">def</span> <span class="nf">test_console_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6168
+ <a id="__codelineno-20-10" name="__codelineno-20-10" href="#__codelineno-20-10"></a> <span class="n">STATUS_ACTIVE</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;Active&#39;</span><span class="p">)</span>
6169
+ <a id="__codelineno-20-11" name="__codelineno-20-11" href="#__codelineno-20-11"></a>
6170
+ <a id="__codelineno-20-12" name="__codelineno-20-12" href="#__codelineno-20-12"></a> <span class="c1"># Check that every console port for every active device has a connection defined.</span>
6171
+ <a id="__codelineno-20-13" name="__codelineno-20-13" href="#__codelineno-20-13"></a> <span class="k">for</span> <span class="n">console_port</span> <span class="ow">in</span> <span class="n">ConsolePort</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">select_related</span><span class="p">(</span><span class="s1">&#39;device&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">device__status</span><span class="o">=</span><span class="n">STATUS_ACTIVE</span><span class="p">):</span>
6172
+ <a id="__codelineno-20-14" name="__codelineno-20-14" href="#__codelineno-20-14"></a> <span class="k">if</span> <span class="n">console_port</span><span class="o">.</span><span class="n">connected_endpoint</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
6173
+ <a id="__codelineno-20-15" name="__codelineno-20-15" href="#__codelineno-20-15"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
6174
+ <a id="__codelineno-20-16" name="__codelineno-20-16" href="#__codelineno-20-16"></a> <span class="s2">&quot;No console connection defined for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span>
6175
+ <a id="__codelineno-20-17" name="__codelineno-20-17" href="#__codelineno-20-17"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6176
+ <a id="__codelineno-20-18" name="__codelineno-20-18" href="#__codelineno-20-18"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6177
+ <a id="__codelineno-20-19" name="__codelineno-20-19" href="#__codelineno-20-19"></a> <span class="p">)</span>
6178
+ <a id="__codelineno-20-20" name="__codelineno-20-20" href="#__codelineno-20-20"></a> <span class="k">elif</span> <span class="ow">not</span> <span class="n">console_port</span><span class="o">.</span><span class="n">connection_status</span><span class="p">:</span>
6179
+ <a id="__codelineno-20-21" name="__codelineno-20-21" href="#__codelineno-20-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
6180
+ <a id="__codelineno-20-22" name="__codelineno-20-22" href="#__codelineno-20-22"></a> <span class="s2">&quot;Console connection for </span><span class="si">%s</span><span class="s2"> marked as planned&quot;</span><span class="p">,</span>
6181
+ <a id="__codelineno-20-23" name="__codelineno-20-23" href="#__codelineno-20-23"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6182
+ <a id="__codelineno-20-24" name="__codelineno-20-24" href="#__codelineno-20-24"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6183
+ <a id="__codelineno-20-25" name="__codelineno-20-25" href="#__codelineno-20-25"></a> <span class="p">)</span>
6184
+ <a id="__codelineno-20-26" name="__codelineno-20-26" href="#__codelineno-20-26"></a> <span class="k">else</span><span class="p">:</span>
6185
+ <a id="__codelineno-20-27" name="__codelineno-20-27" href="#__codelineno-20-27"></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>
6186
+ <a id="__codelineno-20-28" name="__codelineno-20-28" href="#__codelineno-20-28"></a> <span class="s2">&quot;Console port </span><span class="si">%s</span><span class="s2"> has a connection defined&quot;</span><span class="p">,</span>
6187
+ <a id="__codelineno-20-29" name="__codelineno-20-29" href="#__codelineno-20-29"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6188
+ <a id="__codelineno-20-30" name="__codelineno-20-30" href="#__codelineno-20-30"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
6189
+ <a id="__codelineno-20-31" name="__codelineno-20-31" href="#__codelineno-20-31"></a> <span class="p">)</span>
6190
+ <a id="__codelineno-20-32" name="__codelineno-20-32" href="#__codelineno-20-32"></a>
6191
+ <a id="__codelineno-20-33" name="__codelineno-20-33" href="#__codelineno-20-33"></a> <span class="k">def</span> <span class="nf">test_power_connections</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
6192
+ <a id="__codelineno-20-34" name="__codelineno-20-34" href="#__codelineno-20-34"></a> <span class="n">STATUS_ACTIVE</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;Active&#39;</span><span class="p">)</span>
6193
+ <a id="__codelineno-20-35" name="__codelineno-20-35" href="#__codelineno-20-35"></a>
6194
+ <a id="__codelineno-20-36" name="__codelineno-20-36" href="#__codelineno-20-36"></a> <span class="c1"># Check that every active device has at least two connected power supplies.</span>
6195
+ <a id="__codelineno-20-37" name="__codelineno-20-37" href="#__codelineno-20-37"></a> <span class="k">for</span> <span class="n">device</span> <span class="ow">in</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="n">STATUS_ACTIVE</span><span class="p">):</span>
6196
+ <a id="__codelineno-20-38" name="__codelineno-20-38" href="#__codelineno-20-38"></a> <span class="n">connected_ports</span> <span class="o">=</span> <span class="mi">0</span>
6197
+ <a id="__codelineno-20-39" name="__codelineno-20-39" href="#__codelineno-20-39"></a> <span class="k">for</span> <span class="n">power_port</span> <span class="ow">in</span> <span class="n">PowerPort</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">):</span>
6198
+ <a id="__codelineno-20-40" name="__codelineno-20-40" href="#__codelineno-20-40"></a> <span class="k">if</span> <span class="n">power_port</span><span class="o">.</span><span class="n">connected_endpoint</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
6199
+ <a id="__codelineno-20-41" name="__codelineno-20-41" href="#__codelineno-20-41"></a> <span class="n">connected_ports</span> <span class="o">+=</span> <span class="mi">1</span>
6200
+ <a id="__codelineno-20-42" name="__codelineno-20-42" href="#__codelineno-20-42"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">power_port</span><span class="o">.</span><span class="n">connection_status</span><span class="p">:</span>
6201
+ <a id="__codelineno-20-43" name="__codelineno-20-43" href="#__codelineno-20-43"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
6202
+ <a id="__codelineno-20-44" name="__codelineno-20-44" href="#__codelineno-20-44"></a> <span class="s2">&quot;Power connection for </span><span class="si">%s</span><span class="s2"> marked as planned&quot;</span><span class="p">,</span>
6203
+ <a id="__codelineno-20-45" name="__codelineno-20-45" href="#__codelineno-20-45"></a> <span class="n">power_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
6204
+ <a id="__codelineno-20-46" name="__codelineno-20-46" href="#__codelineno-20-46"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
6205
+ <a id="__codelineno-20-47" name="__codelineno-20-47" href="#__codelineno-20-47"></a> <span class="p">)</span>
6206
+ <a id="__codelineno-20-48" name="__codelineno-20-48" href="#__codelineno-20-48"></a> <span class="k">if</span> <span class="n">connected_ports</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
6207
+ <a id="__codelineno-20-49" name="__codelineno-20-49" href="#__codelineno-20-49"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
6208
+ <a id="__codelineno-20-50" name="__codelineno-20-50" href="#__codelineno-20-50"></a> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> connected power supplies found (2 needed)&quot;</span><span class="p">,</span>
6209
+ <a id="__codelineno-20-51" name="__codelineno-20-51" href="#__codelineno-20-51"></a> <span class="n">connected_ports</span><span class="p">,</span>
6210
+ <a id="__codelineno-20-52" name="__codelineno-20-52" href="#__codelineno-20-52"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
6211
+ <a id="__codelineno-20-53" name="__codelineno-20-53" href="#__codelineno-20-53"></a> <span class="p">)</span>
6212
+ <a id="__codelineno-20-54" name="__codelineno-20-54" href="#__codelineno-20-54"></a> <span class="k">else</span><span class="p">:</span>
6213
+ <a id="__codelineno-20-55" name="__codelineno-20-55" href="#__codelineno-20-55"></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;At least two connected power supplies found&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">device</span><span class="p">})</span>
6168
6214
  </code></pre></div>
6169
6215
  <h2 id="job-button-receivers">Job Button Receivers<a class="headerlink" href="#job-button-receivers" title="Permanent link">&para;</a></h2>
6170
6216
  <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>
@@ -6178,52 +6224,52 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
6178
6224
  <li><code>obj</code> - An instance of the object where the button was pressed</li>
6179
6225
  </ol>
6180
6226
  <h3 id="example-job-button-receiver">Example Job Button Receiver<a class="headerlink" href="#example-job-button-receiver" title="Permanent link">&para;</a></h3>
6181
- <div class="highlight"><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span>
6182
- <a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>
6183
- <a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a>
6184
- <a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="k">class</span> <span class="nc">ExampleSimpleJobButtonReceiver</span><span class="p">(</span><span class="n">JobButtonReceiver</span><span class="p">):</span>
6185
- <a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6186
- <a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Simple Job Button Receiver&quot;</span>
6187
- <a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a>
6188
- <a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a> <span class="k">def</span> <span class="nf">receive_job_button</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6189
- <a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></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;Running Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6190
- <a id="__codelineno-20-10" name="__codelineno-20-10" href="#__codelineno-20-10"></a> <span class="c1"># Add job logic here</span>
6227
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span>
6228
+ <a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>
6229
+ <a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
6230
+ <a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="k">class</span> <span class="nc">ExampleSimpleJobButtonReceiver</span><span class="p">(</span><span class="n">JobButtonReceiver</span><span class="p">):</span>
6231
+ <a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6232
+ <a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Simple Job Button Receiver&quot;</span>
6233
+ <a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a>
6234
+ <a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a> <span class="k">def</span> <span class="nf">receive_job_button</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6235
+ <a id="__codelineno-21-9" name="__codelineno-21-9" href="#__codelineno-21-9"></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;Running Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6236
+ <a id="__codelineno-21-10" name="__codelineno-21-10" href="#__codelineno-21-10"></a> <span class="c1"># Add job logic here</span>
6191
6237
  </code></pre></div>
6192
6238
  <h3 id="job-buttons-for-multiple-types">Job Buttons for Multiple Types<a class="headerlink" href="#job-buttons-for-multiple-types" title="Permanent link">&para;</a></h3>
6193
6239
  <p>Since Job Buttons can be associated to multiple object types, it would be trivial to create a Job that can change what it runs based on the object type.</p>
6194
- <div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span>
6195
- <a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Location</span>
6196
- <a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a>
6197
- <a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a>
6198
- <a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="k">class</span> <span class="nc">ExampleComplexJobButtonReceiver</span><span class="p">(</span><span class="n">JobButtonReceiver</span><span class="p">):</span>
6199
- <a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6200
- <a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Complex Job Button Receiver&quot;</span>
6201
- <a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a>
6202
- <a id="__codelineno-21-9" name="__codelineno-21-9" href="#__codelineno-21-9"></a> <span class="k">def</span> <span class="nf">_run_location_job</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6203
- <a id="__codelineno-21-10" name="__codelineno-21-10" href="#__codelineno-21-10"></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;Running Location Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6204
- <a id="__codelineno-21-11" name="__codelineno-21-11" href="#__codelineno-21-11"></a> <span class="c1"># Run Location Job function</span>
6205
- <a id="__codelineno-21-12" name="__codelineno-21-12" href="#__codelineno-21-12"></a>
6206
- <a id="__codelineno-21-13" name="__codelineno-21-13" href="#__codelineno-21-13"></a> <span class="k">def</span> <span class="nf">_run_device_job</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6207
- <a id="__codelineno-21-14" name="__codelineno-21-14" href="#__codelineno-21-14"></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;Running Device Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6208
- <a id="__codelineno-21-15" name="__codelineno-21-15" href="#__codelineno-21-15"></a> <span class="c1"># Run Device Job function</span>
6209
- <a id="__codelineno-21-16" name="__codelineno-21-16" href="#__codelineno-21-16"></a>
6210
- <a id="__codelineno-21-17" name="__codelineno-21-17" href="#__codelineno-21-17"></a> <span class="k">def</span> <span class="nf">receive_job_button</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6211
- <a id="__codelineno-21-18" name="__codelineno-21-18" href="#__codelineno-21-18"></a> <span class="n">user</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span>
6212
- <a id="__codelineno-21-19" name="__codelineno-21-19" href="#__codelineno-21-19"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Location</span><span class="p">):</span>
6213
- <a id="__codelineno-21-20" name="__codelineno-21-20" href="#__codelineno-21-20"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s2">&quot;dcim.add_location&quot;</span><span class="p">):</span>
6214
- <a id="__codelineno-21-21" name="__codelineno-21-21" href="#__codelineno-21-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;User &#39;</span><span class="si">%s</span><span class="s2">&#39; does not have permission to add a Location.&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6215
- <a id="__codelineno-21-22" name="__codelineno-21-22" href="#__codelineno-21-22"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;User does not have permission to add a Location.&quot;</span><span class="p">)</span>
6216
- <a id="__codelineno-21-23" name="__codelineno-21-23" href="#__codelineno-21-23"></a> <span class="k">else</span><span class="p">:</span>
6217
- <a id="__codelineno-21-24" name="__codelineno-21-24" href="#__codelineno-21-24"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_run_location_job</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
6218
- <a id="__codelineno-21-25" name="__codelineno-21-25" href="#__codelineno-21-25"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Device</span><span class="p">):</span>
6219
- <a id="__codelineno-21-26" name="__codelineno-21-26" href="#__codelineno-21-26"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s2">&quot;dcim.add_device&quot;</span><span class="p">):</span>
6220
- <a id="__codelineno-21-27" name="__codelineno-21-27" href="#__codelineno-21-27"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;User &#39;</span><span class="si">%s</span><span class="s2">&#39; does not have permission to add a Device.&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6221
- <a id="__codelineno-21-28" name="__codelineno-21-28" href="#__codelineno-21-28"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;User does not have permission to add a Device.&quot;</span><span class="p">)</span>
6222
- <a id="__codelineno-21-29" name="__codelineno-21-29" href="#__codelineno-21-29"></a> <span class="k">else</span><span class="p">:</span>
6223
- <a id="__codelineno-21-30" name="__codelineno-21-30" href="#__codelineno-21-30"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_run_device_job</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
6224
- <a id="__codelineno-21-31" name="__codelineno-21-31" href="#__codelineno-21-31"></a> <span class="k">else</span><span class="p">:</span>
6225
- <a id="__codelineno-21-32" name="__codelineno-21-32" href="#__codelineno-21-32"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Unable to run Job Button for type </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6226
- <a id="__codelineno-21-33" name="__codelineno-21-33" href="#__codelineno-21-33"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Job button called on unsupported object type.&quot;</span><span class="p">)</span>
6240
+ <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">JobButtonReceiver</span>
6241
+ <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Location</span>
6242
+ <a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>
6243
+ <a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a>
6244
+ <a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="k">class</span> <span class="nc">ExampleComplexJobButtonReceiver</span><span class="p">(</span><span class="n">JobButtonReceiver</span><span class="p">):</span>
6245
+ <a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
6246
+ <a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Complex Job Button Receiver&quot;</span>
6247
+ <a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a>
6248
+ <a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a> <span class="k">def</span> <span class="nf">_run_location_job</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6249
+ <a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></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;Running Location Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6250
+ <a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a> <span class="c1"># Run Location Job function</span>
6251
+ <a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a>
6252
+ <a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></a> <span class="k">def</span> <span class="nf">_run_device_job</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6253
+ <a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></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;Running Device Job Button Receiver.&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6254
+ <a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a> <span class="c1"># Run Device Job function</span>
6255
+ <a id="__codelineno-22-16" name="__codelineno-22-16" href="#__codelineno-22-16"></a>
6256
+ <a id="__codelineno-22-17" name="__codelineno-22-17" href="#__codelineno-22-17"></a> <span class="k">def</span> <span class="nf">receive_job_button</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
6257
+ <a id="__codelineno-22-18" name="__codelineno-22-18" href="#__codelineno-22-18"></a> <span class="n">user</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span>
6258
+ <a id="__codelineno-22-19" name="__codelineno-22-19" href="#__codelineno-22-19"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Location</span><span class="p">):</span>
6259
+ <a id="__codelineno-22-20" name="__codelineno-22-20" href="#__codelineno-22-20"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s2">&quot;dcim.add_location&quot;</span><span class="p">):</span>
6260
+ <a id="__codelineno-22-21" name="__codelineno-22-21" href="#__codelineno-22-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;User &#39;</span><span class="si">%s</span><span class="s2">&#39; does not have permission to add a Location.&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6261
+ <a id="__codelineno-22-22" name="__codelineno-22-22" href="#__codelineno-22-22"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;User does not have permission to add a Location.&quot;</span><span class="p">)</span>
6262
+ <a id="__codelineno-22-23" name="__codelineno-22-23" href="#__codelineno-22-23"></a> <span class="k">else</span><span class="p">:</span>
6263
+ <a id="__codelineno-22-24" name="__codelineno-22-24" href="#__codelineno-22-24"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_run_location_job</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
6264
+ <a id="__codelineno-22-25" name="__codelineno-22-25" href="#__codelineno-22-25"></a> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Device</span><span class="p">):</span>
6265
+ <a id="__codelineno-22-26" name="__codelineno-22-26" href="#__codelineno-22-26"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">user</span><span class="o">.</span><span class="n">has_perm</span><span class="p">(</span><span class="s2">&quot;dcim.add_device&quot;</span><span class="p">):</span>
6266
+ <a id="__codelineno-22-27" name="__codelineno-22-27" href="#__codelineno-22-27"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;User &#39;</span><span class="si">%s</span><span class="s2">&#39; does not have permission to add a Device.&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6267
+ <a id="__codelineno-22-28" name="__codelineno-22-28" href="#__codelineno-22-28"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;User does not have permission to add a Device.&quot;</span><span class="p">)</span>
6268
+ <a id="__codelineno-22-29" name="__codelineno-22-29" href="#__codelineno-22-29"></a> <span class="k">else</span><span class="p">:</span>
6269
+ <a id="__codelineno-22-30" name="__codelineno-22-30" href="#__codelineno-22-30"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_run_device_job</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
6270
+ <a id="__codelineno-22-31" name="__codelineno-22-31" href="#__codelineno-22-31"></a> <span class="k">else</span><span class="p">:</span>
6271
+ <a id="__codelineno-22-32" name="__codelineno-22-32" href="#__codelineno-22-32"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Unable to run Job Button for type </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
6272
+ <a id="__codelineno-22-33" name="__codelineno-22-33" href="#__codelineno-22-33"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Job button called on unsupported object type.&quot;</span><span class="p">)</span>
6227
6273
  </code></pre></div>
6228
6274
  <h2 id="job-hook-receivers">Job Hook Receivers<a class="headerlink" href="#job-hook-receivers" title="Permanent link">&para;</a></h2>
6229
6275
  <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>
@@ -6236,37 +6282,37 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
6236
6282
  <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>
6237
6283
  </div>
6238
6284
  <h3 id="example-job-hook-receiver">Example Job Hook Receiver<a class="headerlink" href="#example-job-hook-receiver" title="Permanent link">&para;</a></h3>
6239
- <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">JobHookReceiver</span>
6240
- <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.choices</span> <span class="kn">import</span> <span class="n">ObjectChangeActionChoices</span>
6241
- <a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>
6242
- <a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a>
6243
- <a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="k">class</span> <span class="nc">ExampleJobHookReceiver</span><span class="p">(</span><span class="n">JobHookReceiver</span><span class="p">):</span>
6244
- <a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a> <span class="k">def</span> <span class="nf">receive_job_hook</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">change</span><span class="p">,</span> <span class="n">action</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">):</span>
6245
- <a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a> <span class="c1"># return on delete action</span>
6246
- <a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a> <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="n">ObjectChangeActionChoices</span><span class="o">.</span><span class="n">ACTION_DELETE</span><span class="p">:</span>
6247
- <a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a> <span class="k">return</span>
6248
- <a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a>
6249
- <a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a> <span class="c1"># log diff output</span>
6250
- <a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a> <span class="n">snapshots</span> <span class="o">=</span> <span class="n">change</span><span class="o">.</span><span class="n">get_snapshots</span><span class="p">()</span>
6251
- <a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></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;DIFF: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">snapshots</span><span class="p">[</span><span class="s1">&#39;differences&#39;</span><span class="p">])</span>
6252
- <a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a>
6253
- <a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a> <span class="c1"># validate changes to serial field</span>
6254
- <a id="__codelineno-22-16" name="__codelineno-22-16" href="#__codelineno-22-16"></a> <span class="k">if</span> <span class="s2">&quot;serial&quot;</span> <span class="ow">in</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;added&quot;</span><span class="p">]:</span>
6255
- <a id="__codelineno-22-17" name="__codelineno-22-17" href="#__codelineno-22-17"></a> <span class="n">old_serial</span> <span class="o">=</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;removed&quot;</span><span class="p">][</span><span class="s2">&quot;serial&quot;</span><span class="p">]</span>
6256
- <a id="__codelineno-22-18" name="__codelineno-22-18" href="#__codelineno-22-18"></a> <span class="n">new_serial</span> <span class="o">=</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;added&quot;</span><span class="p">][</span><span class="s2">&quot;serial&quot;</span><span class="p">]</span>
6257
- <a id="__codelineno-22-19" name="__codelineno-22-19" href="#__codelineno-22-19"></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;</span><span class="si">%s</span><span class="s2"> serial has been changed from </span><span class="si">%s</span><span class="s2"> to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">,</span> <span class="n">old_serial</span><span class="p">,</span> <span class="n">new_serial</span><span class="p">)</span>
6258
- <a id="__codelineno-22-20" name="__codelineno-22-20" href="#__codelineno-22-20"></a>
6259
- <a id="__codelineno-22-21" name="__codelineno-22-21" href="#__codelineno-22-21"></a> <span class="c1"># Check the new serial is valid and revert if necessary</span>
6260
- <a id="__codelineno-22-22" name="__codelineno-22-22" href="#__codelineno-22-22"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">validate_serial</span><span class="p">(</span><span class="n">new_serial</span><span class="p">):</span>
6261
- <a id="__codelineno-22-23" name="__codelineno-22-23" href="#__codelineno-22-23"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">serial</span> <span class="o">=</span> <span class="n">old_serial</span>
6262
- <a id="__codelineno-22-24" name="__codelineno-22-24" href="#__codelineno-22-24"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
6263
- <a id="__codelineno-22-25" name="__codelineno-22-25" href="#__codelineno-22-25"></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;</span><span class="si">%s</span><span class="s2"> serial </span><span class="si">%s</span><span class="s2"> was not valid. Reverted to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">,</span> <span class="n">new_serial</span><span class="p">,</span> <span class="n">old_serial</span><span class="p">)</span>
6264
- <a id="__codelineno-22-26" name="__codelineno-22-26" href="#__codelineno-22-26"></a>
6265
- <a id="__codelineno-22-27" name="__codelineno-22-27" href="#__codelineno-22-27"></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;Serial validation completed for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">)</span>
6266
- <a id="__codelineno-22-28" name="__codelineno-22-28" href="#__codelineno-22-28"></a>
6267
- <a id="__codelineno-22-29" name="__codelineno-22-29" href="#__codelineno-22-29"></a> <span class="k">def</span> <span class="nf">validate_serial</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serial</span><span class="p">):</span>
6268
- <a id="__codelineno-22-30" name="__codelineno-22-30" href="#__codelineno-22-30"></a> <span class="c1"># add business logic to validate serial</span>
6269
- <a id="__codelineno-22-31" name="__codelineno-22-31" href="#__codelineno-22-31"></a> <span class="k">return</span> <span class="kc">False</span>
6285
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span>
6286
+ <a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.choices</span> <span class="kn">import</span> <span class="n">ObjectChangeActionChoices</span>
6287
+ <a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a>
6288
+ <a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a>
6289
+ <a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="k">class</span> <span class="nc">ExampleJobHookReceiver</span><span class="p">(</span><span class="n">JobHookReceiver</span><span class="p">):</span>
6290
+ <a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a> <span class="k">def</span> <span class="nf">receive_job_hook</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">change</span><span class="p">,</span> <span class="n">action</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">):</span>
6291
+ <a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a> <span class="c1"># return on delete action</span>
6292
+ <a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a> <span class="k">if</span> <span class="n">action</span> <span class="o">==</span> <span class="n">ObjectChangeActionChoices</span><span class="o">.</span><span class="n">ACTION_DELETE</span><span class="p">:</span>
6293
+ <a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a> <span class="k">return</span>
6294
+ <a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a>
6295
+ <a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a> <span class="c1"># log diff output</span>
6296
+ <a id="__codelineno-23-12" name="__codelineno-23-12" href="#__codelineno-23-12"></a> <span class="n">snapshots</span> <span class="o">=</span> <span class="n">change</span><span class="o">.</span><span class="n">get_snapshots</span><span class="p">()</span>
6297
+ <a id="__codelineno-23-13" name="__codelineno-23-13" href="#__codelineno-23-13"></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;DIFF: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">snapshots</span><span class="p">[</span><span class="s1">&#39;differences&#39;</span><span class="p">])</span>
6298
+ <a id="__codelineno-23-14" name="__codelineno-23-14" href="#__codelineno-23-14"></a>
6299
+ <a id="__codelineno-23-15" name="__codelineno-23-15" href="#__codelineno-23-15"></a> <span class="c1"># validate changes to serial field</span>
6300
+ <a id="__codelineno-23-16" name="__codelineno-23-16" href="#__codelineno-23-16"></a> <span class="k">if</span> <span class="s2">&quot;serial&quot;</span> <span class="ow">in</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;added&quot;</span><span class="p">]:</span>
6301
+ <a id="__codelineno-23-17" name="__codelineno-23-17" href="#__codelineno-23-17"></a> <span class="n">old_serial</span> <span class="o">=</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;removed&quot;</span><span class="p">][</span><span class="s2">&quot;serial&quot;</span><span class="p">]</span>
6302
+ <a id="__codelineno-23-18" name="__codelineno-23-18" href="#__codelineno-23-18"></a> <span class="n">new_serial</span> <span class="o">=</span> <span class="n">snapshots</span><span class="p">[</span><span class="s2">&quot;differences&quot;</span><span class="p">][</span><span class="s2">&quot;added&quot;</span><span class="p">][</span><span class="s2">&quot;serial&quot;</span><span class="p">]</span>
6303
+ <a id="__codelineno-23-19" name="__codelineno-23-19" href="#__codelineno-23-19"></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;</span><span class="si">%s</span><span class="s2"> serial has been changed from </span><span class="si">%s</span><span class="s2"> to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">,</span> <span class="n">old_serial</span><span class="p">,</span> <span class="n">new_serial</span><span class="p">)</span>
6304
+ <a id="__codelineno-23-20" name="__codelineno-23-20" href="#__codelineno-23-20"></a>
6305
+ <a id="__codelineno-23-21" name="__codelineno-23-21" href="#__codelineno-23-21"></a> <span class="c1"># Check the new serial is valid and revert if necessary</span>
6306
+ <a id="__codelineno-23-22" name="__codelineno-23-22" href="#__codelineno-23-22"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">validate_serial</span><span class="p">(</span><span class="n">new_serial</span><span class="p">):</span>
6307
+ <a id="__codelineno-23-23" name="__codelineno-23-23" href="#__codelineno-23-23"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">serial</span> <span class="o">=</span> <span class="n">old_serial</span>
6308
+ <a id="__codelineno-23-24" name="__codelineno-23-24" href="#__codelineno-23-24"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
6309
+ <a id="__codelineno-23-25" name="__codelineno-23-25" href="#__codelineno-23-25"></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;</span><span class="si">%s</span><span class="s2"> serial </span><span class="si">%s</span><span class="s2"> was not valid. Reverted to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">,</span> <span class="n">new_serial</span><span class="p">,</span> <span class="n">old_serial</span><span class="p">)</span>
6310
+ <a id="__codelineno-23-26" name="__codelineno-23-26" href="#__codelineno-23-26"></a>
6311
+ <a id="__codelineno-23-27" name="__codelineno-23-27" href="#__codelineno-23-27"></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;Serial validation completed for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">changed_object</span><span class="p">)</span>
6312
+ <a id="__codelineno-23-28" name="__codelineno-23-28" href="#__codelineno-23-28"></a>
6313
+ <a id="__codelineno-23-29" name="__codelineno-23-29" href="#__codelineno-23-29"></a> <span class="k">def</span> <span class="nf">validate_serial</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serial</span><span class="p">):</span>
6314
+ <a id="__codelineno-23-30" name="__codelineno-23-30" href="#__codelineno-23-30"></a> <span class="c1"># add business logic to validate serial</span>
6315
+ <a id="__codelineno-23-31" name="__codelineno-23-31" href="#__codelineno-23-31"></a> <span class="k">return</span> <span class="kc">False</span>
6270
6316
  </code></pre></div>
6271
6317
  <h3 id="the-receive_job_hook-method">The <code>receive_job_hook()</code> Method<a class="headerlink" href="#the-receive_job_hook-method" title="Permanent link">&para;</a></h3>
6272
6318
  <p>All <code>JobHookReceiver</code> subclasses must implement a <code>receive_job_hook()</code> method. This method accepts three arguments:</p>