nautobot 2.2.8__py3-none-any.whl → 2.3.0__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 (704) hide show
  1. nautobot/apps/forms.py +4 -0
  2. nautobot/apps/models.py +10 -1
  3. nautobot/circuits/__init__.py +0 -1
  4. nautobot/circuits/apps.py +1 -0
  5. nautobot/circuits/factory.py +15 -3
  6. nautobot/circuits/filters.py +13 -0
  7. nautobot/circuits/forms.py +13 -0
  8. nautobot/circuits/migrations/0021_alter_circuit_status_alter_circuittermination__path.py +32 -0
  9. nautobot/circuits/migrations/0022_circuittermination_cloud_network.py +25 -0
  10. nautobot/circuits/models.py +16 -3
  11. nautobot/circuits/tables.py +16 -2
  12. nautobot/circuits/templates/circuits/circuittermination_create.html +10 -2
  13. nautobot/circuits/templates/circuits/circuittermination_retrieve.html +6 -0
  14. nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -1
  15. nautobot/circuits/tests/test_api.py +7 -5
  16. nautobot/circuits/tests/test_filters.py +12 -5
  17. nautobot/circuits/tests/test_models.py +33 -2
  18. nautobot/circuits/views.py +2 -3
  19. nautobot/cloud/__init__.py +0 -0
  20. nautobot/cloud/api/__init__.py +0 -0
  21. nautobot/cloud/api/serializers.py +54 -0
  22. nautobot/cloud/api/urls.py +16 -0
  23. nautobot/cloud/api/views.py +48 -0
  24. nautobot/cloud/apps.py +13 -0
  25. nautobot/cloud/factory.py +113 -0
  26. nautobot/cloud/filters.py +187 -0
  27. nautobot/cloud/forms.py +339 -0
  28. nautobot/cloud/homepage.py +43 -0
  29. nautobot/cloud/migrations/0001_initial.py +304 -0
  30. nautobot/cloud/migrations/__init__.py +0 -0
  31. nautobot/cloud/models.py +246 -0
  32. nautobot/cloud/navigation.py +85 -0
  33. nautobot/cloud/tables.py +157 -0
  34. nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +43 -0
  35. nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +122 -0
  36. nautobot/cloud/templates/cloud/cloudnetwork_update.html +33 -0
  37. nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +111 -0
  38. nautobot/cloud/templates/cloud/cloudservice_retrieve.html +69 -0
  39. nautobot/cloud/templates/cloud/cloudservice_update.html +25 -0
  40. nautobot/cloud/tests/__init__.py +0 -0
  41. nautobot/cloud/tests/test_api.py +248 -0
  42. nautobot/cloud/tests/test_filters.py +125 -0
  43. nautobot/cloud/tests/test_models.py +43 -0
  44. nautobot/cloud/tests/test_views.py +153 -0
  45. nautobot/cloud/urls.py +14 -0
  46. nautobot/cloud/views.py +181 -0
  47. nautobot/core/__init__.py +0 -3
  48. nautobot/core/api/metadata.py +1 -0
  49. nautobot/core/api/parsers.py +7 -1
  50. nautobot/core/api/urls.py +1 -0
  51. nautobot/core/api/utils.py +1 -0
  52. nautobot/core/api/views.py +4 -0
  53. nautobot/core/apps/__init__.py +6 -3
  54. nautobot/core/constants.py +8 -0
  55. nautobot/core/factory.py +32 -1
  56. nautobot/core/filters.py +110 -14
  57. nautobot/core/forms/fields.py +10 -4
  58. nautobot/core/forms/forms.py +11 -3
  59. nautobot/core/forms/widgets.py +18 -1
  60. nautobot/core/graphql/generators.py +2 -2
  61. nautobot/core/graphql/schema.py +28 -7
  62. nautobot/core/jobs/__init__.py +20 -3
  63. nautobot/core/jobs/cleanup.py +100 -0
  64. nautobot/core/jobs/groups.py +38 -0
  65. nautobot/core/management/commands/generate_test_data.py +116 -3
  66. nautobot/core/models/__init__.py +34 -9
  67. nautobot/core/models/generics.py +19 -3
  68. nautobot/core/models/name_color_content_types.py +7 -28
  69. nautobot/core/models/querysets.py +4 -3
  70. nautobot/core/models/tree_queries.py +1 -1
  71. nautobot/core/models/utils.py +21 -5
  72. nautobot/core/settings.py +15 -19
  73. nautobot/core/settings.yaml +48 -13
  74. nautobot/core/settings_funcs.py +103 -0
  75. nautobot/core/tables.py +130 -56
  76. nautobot/core/templates/admin/search_form.html +1 -1
  77. nautobot/core/templates/buttons/add.html +11 -3
  78. nautobot/core/templates/buttons/consolidated_bulk_action_buttons.html +13 -0
  79. nautobot/core/templates/buttons/consolidated_detail_view_action_buttons.html +13 -0
  80. nautobot/core/templates/buttons/export.html +101 -53
  81. nautobot/core/templates/buttons/job_import.html +11 -3
  82. nautobot/core/templates/generic/object_bulk_destroy.html +3 -1
  83. nautobot/core/templates/generic/object_bulk_update.html +3 -1
  84. nautobot/core/templates/generic/object_changelog.html +0 -9
  85. nautobot/core/templates/generic/object_list.html +156 -17
  86. nautobot/core/templates/generic/object_retrieve.html +80 -16
  87. nautobot/core/templates/inc/extras_features_edit_form_fields.html +8 -0
  88. nautobot/core/templates/inc/javascript.html +2 -0
  89. nautobot/core/templates/inc/media.html +2 -2
  90. nautobot/core/templates/inc/nav_menu.html +1 -0
  91. nautobot/core/templates/inc/paginator.html +7 -7
  92. nautobot/core/templates/inc/search_panel.html +2 -2
  93. nautobot/core/templates/inc/table.html +2 -2
  94. nautobot/core/templates/nautobot_config.py.j2 +28 -8
  95. nautobot/core/templates/utilities/templatetags/dynamic_group_assignment_modal.html +37 -0
  96. nautobot/core/templates/utilities/templatetags/filter_form_modal.html +2 -2
  97. nautobot/core/templates/utilities/templatetags/saved_view_modal.html +38 -0
  98. nautobot/core/templates/utilities/theme_preview.html +25 -8
  99. nautobot/core/templates/utilities/worker_status.html +152 -0
  100. nautobot/core/templatetags/buttons.py +335 -38
  101. nautobot/core/templatetags/form_helpers.py +1 -1
  102. nautobot/core/templatetags/helpers.py +181 -11
  103. nautobot/core/testing/api.py +5 -4
  104. nautobot/core/testing/filters.py +63 -14
  105. nautobot/core/testing/mixins.py +46 -0
  106. nautobot/core/testing/models.py +22 -0
  107. nautobot/core/testing/schema.py +4 -8
  108. nautobot/core/testing/views.py +31 -14
  109. nautobot/core/tests/integration/test_general_functionality.py +1 -1
  110. nautobot/core/tests/integration/test_import_objects_ui.py +1 -0
  111. nautobot/core/tests/integration/test_swagger.py +1 -1
  112. nautobot/core/tests/nautobot_config.py +0 -1
  113. nautobot/core/tests/runner.py +2 -2
  114. nautobot/core/tests/test_api.py +1 -0
  115. nautobot/core/tests/test_authentication.py +7 -2
  116. nautobot/core/tests/test_filters.py +11 -9
  117. nautobot/core/tests/test_forms.py +9 -0
  118. nautobot/core/tests/test_graphql.py +27 -16
  119. nautobot/core/tests/test_jobs.py +204 -2
  120. nautobot/core/tests/test_tables.py +3 -1
  121. nautobot/core/tests/test_templatetags_helpers.py +12 -5
  122. nautobot/core/tests/test_templatetags_netutils.py +3 -3
  123. nautobot/core/tests/test_utils.py +31 -20
  124. nautobot/core/tests/test_views.py +6 -6
  125. nautobot/core/urls.py +8 -3
  126. nautobot/core/utils/deprecation.py +29 -0
  127. nautobot/core/utils/filtering.py +12 -9
  128. nautobot/core/utils/lookup.py +37 -2
  129. nautobot/core/utils/requests.py +4 -1
  130. nautobot/core/views/__init__.py +137 -24
  131. nautobot/core/views/generic.py +119 -67
  132. nautobot/core/views/mixins.py +105 -36
  133. nautobot/core/views/paginator.py +9 -3
  134. nautobot/core/views/renderers.py +121 -56
  135. nautobot/core/views/utils.py +81 -1
  136. nautobot/dcim/__init__.py +0 -1
  137. nautobot/dcim/api/serializers.py +180 -44
  138. nautobot/dcim/api/urls.py +7 -3
  139. nautobot/dcim/api/views.py +53 -7
  140. nautobot/dcim/apps.py +3 -0
  141. nautobot/dcim/choices.py +25 -0
  142. nautobot/dcim/constants.py +7 -0
  143. nautobot/dcim/factory.py +252 -18
  144. nautobot/dcim/filters/__init__.py +373 -193
  145. nautobot/dcim/filters/mixins.py +274 -1
  146. nautobot/dcim/forms.py +834 -121
  147. nautobot/dcim/graphql/types.py +2 -2
  148. nautobot/dcim/homepage.py +1 -1
  149. nautobot/dcim/migrations/0059_add_role_field_to_interface_models.py +27 -0
  150. nautobot/dcim/migrations/0060_alter_cable_status_alter_consoleport__path_and_more.py +303 -0
  151. nautobot/dcim/migrations/0061_module_models.py +862 -0
  152. nautobot/dcim/migrations/0062_module_data_migration.py +25 -0
  153. nautobot/dcim/models/__init__.py +8 -0
  154. nautobot/dcim/models/cables.py +15 -0
  155. nautobot/dcim/models/device_component_templates.py +207 -53
  156. nautobot/dcim/models/device_components.py +282 -99
  157. nautobot/dcim/models/devices.py +472 -13
  158. nautobot/dcim/models/racks.py +0 -1
  159. nautobot/dcim/navigation.py +47 -0
  160. nautobot/dcim/signals.py +3 -3
  161. nautobot/dcim/tables/__init__.py +35 -23
  162. nautobot/dcim/tables/devices.py +248 -47
  163. nautobot/dcim/tables/devicetypes.py +65 -9
  164. nautobot/dcim/tables/racks.py +5 -1
  165. nautobot/dcim/tables/template_code.py +46 -26
  166. nautobot/dcim/templates/dcim/cable_connect.html +76 -3
  167. nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -5
  168. nautobot/dcim/templates/dcim/device/base.html +14 -6
  169. nautobot/dcim/templates/dcim/device/consoleports.html +2 -3
  170. nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -3
  171. nautobot/dcim/templates/dcim/device/devicebays.html +6 -7
  172. nautobot/dcim/templates/dcim/device/frontports.html +2 -3
  173. nautobot/dcim/templates/dcim/device/interfaces.html +2 -3
  174. nautobot/dcim/templates/dcim/device/inventory.html +2 -3
  175. nautobot/dcim/templates/dcim/device/modulebays.html +49 -0
  176. nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -3
  177. nautobot/dcim/templates/dcim/device/powerports.html +2 -3
  178. nautobot/dcim/templates/dcim/device/rearports.html +2 -3
  179. nautobot/dcim/templates/dcim/device.html +45 -1
  180. nautobot/dcim/templates/dcim/device_component.html +13 -5
  181. nautobot/dcim/templates/dcim/device_list.html +2 -1
  182. nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +6 -0
  183. nautobot/dcim/templates/dcim/devicetype.html +99 -98
  184. nautobot/dcim/templates/dcim/devicetype_list.html +8 -16
  185. nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
  186. nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +39 -0
  187. nautobot/dcim/templates/dcim/interface.html +17 -2
  188. nautobot/dcim/templates/dcim/interface_connection_list.html +7 -5
  189. nautobot/dcim/templates/dcim/interface_edit.html +1 -0
  190. nautobot/dcim/templates/dcim/manufacturer.html +24 -0
  191. nautobot/dcim/templates/dcim/module/base.html +97 -0
  192. nautobot/dcim/templates/dcim/module_bulk_destroy.html +5 -0
  193. nautobot/dcim/templates/dcim/module_consoleports.html +53 -0
  194. nautobot/dcim/templates/dcim/module_consoleserverports.html +53 -0
  195. nautobot/dcim/templates/dcim/module_destroy.html +5 -0
  196. nautobot/dcim/templates/dcim/module_frontports.html +53 -0
  197. nautobot/dcim/templates/dcim/module_interfaces.html +57 -0
  198. nautobot/dcim/templates/dcim/module_list.html +20 -0
  199. nautobot/dcim/templates/dcim/module_modulebays.html +49 -0
  200. nautobot/dcim/templates/dcim/module_poweroutlets.html +53 -0
  201. nautobot/dcim/templates/dcim/module_powerports.html +53 -0
  202. nautobot/dcim/templates/dcim/module_rearports.html +53 -0
  203. nautobot/dcim/templates/dcim/module_retrieve.html +63 -0
  204. nautobot/dcim/templates/dcim/module_update.html +71 -0
  205. nautobot/dcim/templates/dcim/modulebay_bulk_destroy.html +5 -0
  206. nautobot/dcim/templates/dcim/modulebay_destroy.html +8 -0
  207. nautobot/dcim/templates/dcim/modulebay_retrieve.html +101 -0
  208. nautobot/dcim/templates/dcim/moduletype_list.html +11 -0
  209. nautobot/dcim/templates/dcim/moduletype_retrieve.html +159 -0
  210. nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -5
  211. nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +65 -19
  212. nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
  213. nautobot/dcim/tests/test_api.py +693 -208
  214. nautobot/dcim/tests/test_filters.py +843 -217
  215. nautobot/dcim/tests/test_models.py +1103 -8
  216. nautobot/dcim/tests/test_views.py +1525 -343
  217. nautobot/dcim/urls.py +17 -2
  218. nautobot/dcim/utils.py +2 -3
  219. nautobot/dcim/views.py +1109 -113
  220. nautobot/extras/__init__.py +0 -1
  221. nautobot/extras/api/serializers.py +115 -3
  222. nautobot/extras/api/urls.py +12 -0
  223. nautobot/extras/api/views.py +73 -59
  224. nautobot/extras/apps.py +2 -2
  225. nautobot/extras/choices.py +43 -0
  226. nautobot/extras/context_managers.py +13 -8
  227. nautobot/extras/datasources/git.py +2 -0
  228. nautobot/extras/factory.py +460 -9
  229. nautobot/extras/filters/__init__.py +174 -3
  230. nautobot/extras/filters/mixins.py +46 -43
  231. nautobot/extras/forms/base.py +24 -5
  232. nautobot/extras/forms/forms.py +227 -8
  233. nautobot/extras/forms/mixins.py +93 -0
  234. nautobot/extras/graphql/types.py +23 -10
  235. nautobot/extras/homepage.py +26 -3
  236. nautobot/extras/jobs.py +2 -2
  237. nautobot/extras/management/__init__.py +1 -0
  238. nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -16
  239. nautobot/extras/migrations/0021_customfield_changelog_data.py +1 -0
  240. nautobot/extras/migrations/0109_dynamicgroup_group_type_dynamicgroup_tags_and_more.py +108 -0
  241. nautobot/extras/migrations/0110_alter_configcontext_cluster_groups_and_more.py +111 -0
  242. nautobot/extras/migrations/0111_metadata.py +162 -0
  243. nautobot/extras/migrations/0112_dynamic_group_group_type_data_migration.py +28 -0
  244. nautobot/extras/migrations/0113_saved_views.py +77 -0
  245. nautobot/extras/models/__init__.py +15 -1
  246. nautobot/extras/models/change_logging.py +3 -3
  247. nautobot/extras/models/contacts.py +4 -0
  248. nautobot/extras/models/customfields.py +18 -3
  249. nautobot/extras/models/groups.py +389 -225
  250. nautobot/extras/models/jobs.py +87 -3
  251. nautobot/extras/models/metadata.py +441 -0
  252. nautobot/extras/models/mixins.py +72 -62
  253. nautobot/extras/models/models.py +118 -9
  254. nautobot/extras/models/relationships.py +9 -2
  255. nautobot/extras/models/tags.py +13 -2
  256. nautobot/extras/navigation.py +57 -0
  257. nautobot/extras/plugins/__init__.py +3 -1
  258. nautobot/extras/querysets.py +30 -66
  259. nautobot/extras/signals.py +109 -101
  260. nautobot/extras/tables.py +201 -17
  261. nautobot/extras/templates/extras/dynamicgroup.html +44 -15
  262. nautobot/extras/templates/extras/dynamicgroup_edit.html +2 -0
  263. nautobot/extras/templates/extras/job.html +1 -1
  264. nautobot/extras/templates/extras/job_detail.html +11 -0
  265. nautobot/extras/templates/extras/jobresult.html +61 -74
  266. nautobot/extras/templates/extras/metadatatype_create.html +89 -0
  267. nautobot/extras/templates/extras/metadatatype_retrieve.html +67 -0
  268. nautobot/extras/templates/extras/object_dynamicgroups.html +7 -0
  269. nautobot/extras/templates/extras/objectchange_list.html +0 -12
  270. nautobot/extras/templates/extras/plugins_list.html +1 -3
  271. nautobot/extras/templates/extras/role_retrieve.html +48 -0
  272. nautobot/extras/templates/extras/staticgroupassociation_retrieve.html +20 -0
  273. nautobot/extras/tests/integration/test_customfields.py +1 -0
  274. nautobot/extras/tests/test_api.py +509 -23
  275. nautobot/extras/tests/test_changelog.py +20 -9
  276. nautobot/extras/tests/test_context_managers.py +22 -15
  277. nautobot/extras/tests/test_datasources.py +13 -1
  278. nautobot/extras/tests/test_dynamicgroups.py +201 -171
  279. nautobot/extras/tests/test_filters.py +211 -12
  280. nautobot/extras/tests/test_jobs.py +6 -6
  281. nautobot/extras/tests/test_models.py +501 -4
  282. nautobot/extras/tests/test_relationships.py +1 -0
  283. nautobot/extras/tests/test_views.py +586 -8
  284. nautobot/extras/tests/test_webhooks.py +1 -1
  285. nautobot/extras/urls.py +5 -0
  286. nautobot/extras/utils.py +85 -16
  287. nautobot/extras/views.py +562 -122
  288. nautobot/ipam/__init__.py +0 -1
  289. nautobot/ipam/apps.py +1 -0
  290. nautobot/ipam/factory.py +17 -19
  291. nautobot/ipam/filters.py +13 -0
  292. nautobot/ipam/forms.py +8 -4
  293. nautobot/ipam/graphql/types.py +2 -2
  294. nautobot/ipam/migrations/0047_alter_ipaddress_role_alter_ipaddress_status_and_more.py +59 -0
  295. nautobot/ipam/models.py +20 -20
  296. nautobot/ipam/querysets.py +1 -1
  297. nautobot/ipam/signals.py +4 -2
  298. nautobot/ipam/tables.py +5 -0
  299. nautobot/ipam/templates/ipam/ipaddress_interfaces.html +1 -1
  300. nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +1 -1
  301. nautobot/ipam/templates/ipam/prefix.html +1 -0
  302. nautobot/ipam/tests/test_api.py +37 -18
  303. nautobot/ipam/tests/test_filters.py +26 -2
  304. nautobot/ipam/tests/test_models.py +9 -2
  305. nautobot/ipam/tests/test_querysets.py +1 -1
  306. nautobot/ipam/tests/test_views.py +3 -2
  307. nautobot/ipam/urls.py +2 -2
  308. nautobot/ipam/views.py +20 -34
  309. nautobot/project-static/css/base.css +21 -0
  310. nautobot/project-static/css/dark.css +11 -0
  311. nautobot/project-static/docs/404.html +894 -90
  312. nautobot/project-static/docs/apps/index.html +894 -90
  313. nautobot/project-static/docs/apps/nautobot-apps.html +894 -90
  314. nautobot/project-static/docs/assets/_mkdocstrings.css +5 -0
  315. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +1 -0
  316. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +1 -0
  317. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +921 -122
  318. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +906 -103
  319. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1620 -905
  320. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +937 -146
  321. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +979 -190
  322. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +903 -101
  323. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +899 -95
  324. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +993 -195
  325. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +976 -133
  326. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +1080 -274
  327. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1244 -336
  328. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1729 -877
  329. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +1166 -383
  330. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2090 -1376
  331. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2248 -1424
  332. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +914 -113
  333. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +965 -165
  334. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1012 -225
  335. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +1915 -1279
  336. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +1848 -1104
  337. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +906 -103
  338. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2335 -1701
  339. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +1804 -1026
  340. nautobot/project-static/docs/development/apps/api/configuration-view.html +894 -90
  341. nautobot/project-static/docs/development/apps/api/database-backend-config.html +894 -90
  342. nautobot/project-static/docs/development/apps/api/models/django-admin.html +894 -90
  343. nautobot/project-static/docs/development/apps/api/models/global-search.html +894 -90
  344. nautobot/project-static/docs/development/apps/api/models/graphql.html +894 -90
  345. nautobot/project-static/docs/development/apps/api/models/index.html +944 -92
  346. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +894 -90
  347. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +894 -90
  348. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +894 -90
  349. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +894 -90
  350. nautobot/project-static/docs/development/apps/api/platform-features/index.html +894 -90
  351. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +894 -90
  352. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +894 -90
  353. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +894 -90
  354. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +894 -90
  355. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +894 -90
  356. nautobot/project-static/docs/development/apps/api/prometheus.html +894 -90
  357. nautobot/project-static/docs/development/apps/api/setup.html +894 -90
  358. nautobot/project-static/docs/development/apps/api/testing.html +894 -90
  359. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +894 -90
  360. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +894 -90
  361. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +894 -90
  362. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +894 -90
  363. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +894 -90
  364. nautobot/project-static/docs/development/apps/api/views/base-template.html +894 -90
  365. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +894 -90
  366. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +894 -90
  367. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +894 -90
  368. nautobot/project-static/docs/development/apps/api/views/index.html +894 -90
  369. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +894 -90
  370. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +894 -90
  371. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +894 -90
  372. nautobot/project-static/docs/development/apps/api/views/notes.html +894 -90
  373. nautobot/project-static/docs/development/apps/api/views/rest-api.html +894 -90
  374. nautobot/project-static/docs/development/apps/api/views/urls.html +894 -90
  375. nautobot/project-static/docs/development/apps/index.html +894 -90
  376. nautobot/project-static/docs/development/apps/migration/code-updates.html +894 -90
  377. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +894 -90
  378. nautobot/project-static/docs/development/apps/migration/from-v1.html +894 -90
  379. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +894 -90
  380. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +894 -90
  381. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +894 -90
  382. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +894 -90
  383. nautobot/project-static/docs/development/apps/porting-from-netbox.html +894 -90
  384. nautobot/project-static/docs/development/core/application-registry.html +894 -90
  385. nautobot/project-static/docs/development/core/best-practices.html +895 -90
  386. nautobot/project-static/docs/development/core/bootstrap-ui.html +894 -90
  387. nautobot/project-static/docs/development/core/caching.html +894 -90
  388. nautobot/project-static/docs/development/core/controllers.html +894 -90
  389. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +894 -90
  390. nautobot/project-static/docs/development/core/generic-views.html +894 -90
  391. nautobot/project-static/docs/development/core/getting-started.html +894 -90
  392. nautobot/project-static/docs/development/core/homepage.html +894 -90
  393. nautobot/project-static/docs/development/core/index.html +905 -90
  394. nautobot/project-static/docs/development/core/model-checklist.html +903 -91
  395. nautobot/project-static/docs/development/core/model-features.html +894 -90
  396. nautobot/project-static/docs/development/core/natural-keys.html +894 -90
  397. nautobot/project-static/docs/development/core/navigation-menu.html +894 -90
  398. nautobot/project-static/docs/development/core/release-checklist.html +897 -93
  399. nautobot/project-static/docs/development/core/role-internals.html +894 -90
  400. nautobot/project-static/docs/development/core/settings.html +894 -90
  401. nautobot/project-static/docs/development/core/style-guide.html +895 -91
  402. nautobot/project-static/docs/development/core/templates.html +906 -91
  403. nautobot/project-static/docs/development/core/testing.html +894 -90
  404. nautobot/project-static/docs/development/core/user-preferences.html +894 -90
  405. nautobot/project-static/docs/development/index.html +894 -90
  406. nautobot/project-static/docs/development/jobs/index.html +1271 -453
  407. nautobot/project-static/docs/development/jobs/migration/from-v1.html +894 -90
  408. nautobot/project-static/docs/index.html +9032 -13
  409. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_dark.png +0 -0
  410. nautobot/project-static/docs/media/models/cloud_aws_direct_connect_light.png +0 -0
  411. nautobot/project-static/docs/models/cloud/cloudaccount.html +15 -0
  412. nautobot/project-static/docs/models/cloud/cloudnetwork.html +15 -0
  413. nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +15 -0
  414. nautobot/project-static/docs/models/cloud/cloudresourcetype.html +15 -0
  415. nautobot/project-static/docs/models/cloud/cloudservice.html +15 -0
  416. nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +15 -0
  417. nautobot/project-static/docs/models/dcim/module.html +15 -0
  418. nautobot/project-static/docs/models/dcim/modulebay.html +15 -0
  419. nautobot/project-static/docs/models/dcim/modulebaytemplate.html +15 -0
  420. nautobot/project-static/docs/models/dcim/moduletype.html +15 -0
  421. nautobot/project-static/docs/models/extras/metadatachoice.html +15 -0
  422. nautobot/project-static/docs/models/extras/metadatatype.html +15 -0
  423. nautobot/project-static/docs/models/extras/objectmetadata.html +15 -0
  424. nautobot/project-static/docs/models/extras/role.html +15 -0
  425. nautobot/project-static/docs/models/extras/savedview.html +15 -0
  426. nautobot/project-static/docs/models/extras/staticgroupassociation.html +15 -0
  427. nautobot/project-static/docs/models/extras/status.html +15 -0
  428. nautobot/project-static/docs/objects.inv +0 -0
  429. nautobot/project-static/docs/overview/application_stack.html +902 -91
  430. nautobot/project-static/docs/overview/design_philosophy.html +896 -92
  431. nautobot/project-static/docs/overview/index.html +13 -8228
  432. nautobot/project-static/docs/release-notes/index.html +1131 -94
  433. nautobot/project-static/docs/release-notes/version-1.0.html +894 -90
  434. nautobot/project-static/docs/release-notes/version-1.1.html +894 -90
  435. nautobot/project-static/docs/release-notes/version-1.2.html +894 -90
  436. nautobot/project-static/docs/release-notes/version-1.3.html +894 -90
  437. nautobot/project-static/docs/release-notes/version-1.4.html +894 -90
  438. nautobot/project-static/docs/release-notes/version-1.5.html +895 -91
  439. nautobot/project-static/docs/release-notes/version-1.6.html +895 -91
  440. nautobot/project-static/docs/release-notes/version-2.0.html +894 -90
  441. nautobot/project-static/docs/release-notes/version-2.1.html +894 -90
  442. nautobot/project-static/docs/release-notes/version-2.2.html +1137 -196
  443. nautobot/project-static/docs/release-notes/version-2.3.html +9954 -0
  444. nautobot/project-static/docs/requirements.txt +5 -5
  445. nautobot/project-static/docs/search/search_index.json +1 -1
  446. nautobot/project-static/docs/sitemap.xml +335 -260
  447. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  448. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +894 -90
  449. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +894 -90
  450. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +894 -90
  451. nautobot/project-static/docs/user-guide/administration/configuration/index.html +894 -90
  452. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +1025 -175
  453. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +894 -90
  454. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +894 -90
  455. nautobot/project-static/docs/user-guide/administration/guides/caching.html +894 -90
  456. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +902 -90
  457. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +894 -90
  458. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +894 -90
  459. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +894 -90
  460. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +894 -90
  461. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +894 -90
  462. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +894 -90
  463. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +894 -90
  464. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +894 -90
  465. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +946 -155
  466. nautobot/project-static/docs/user-guide/administration/installation/index.html +903 -95
  467. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +936 -124
  468. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +956 -159
  469. nautobot/project-static/docs/user-guide/administration/installation/services.html +915 -114
  470. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +910 -101
  471. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +894 -90
  472. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +894 -90
  473. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +894 -90
  474. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +894 -90
  475. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +977 -121
  476. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +894 -90
  477. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +894 -90
  478. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +894 -90
  479. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +894 -90
  480. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +894 -90
  481. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +894 -90
  482. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +894 -90
  483. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +894 -90
  484. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +894 -90
  485. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +894 -90
  486. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +894 -90
  487. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +895 -91
  488. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +894 -90
  489. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +898 -90
  490. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +897 -93
  491. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +8984 -0
  492. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +8828 -0
  493. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +8829 -0
  494. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +8828 -0
  495. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +8829 -0
  496. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +8833 -0
  497. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +8828 -0
  498. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +908 -104
  499. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +925 -107
  500. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +925 -107
  501. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +920 -102
  502. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +925 -107
  503. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +908 -104
  504. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +908 -104
  505. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +915 -107
  506. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +922 -118
  507. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +923 -119
  508. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +920 -116
  509. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +908 -104
  510. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +916 -107
  511. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +928 -110
  512. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +938 -120
  513. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +930 -108
  514. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +908 -104
  515. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +939 -121
  516. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +930 -112
  517. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +920 -116
  518. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +923 -119
  519. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +925 -117
  520. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +8828 -0
  521. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +8846 -0
  522. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +8843 -0
  523. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +8823 -0
  524. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +918 -114
  525. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +908 -104
  526. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +942 -85
  527. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +926 -108
  528. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +908 -104
  529. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +945 -88
  530. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +923 -105
  531. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +931 -127
  532. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +920 -116
  533. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +908 -104
  534. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +924 -106
  535. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +926 -108
  536. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +908 -104
  537. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +908 -104
  538. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +908 -104
  539. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +938 -90
  540. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +894 -90
  541. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +899 -91
  542. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +899 -91
  543. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +894 -90
  544. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +894 -90
  545. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +894 -90
  546. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +894 -90
  547. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +894 -90
  548. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +894 -90
  549. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +894 -90
  550. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +894 -90
  551. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +894 -90
  552. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +894 -90
  553. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +903 -98
  554. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +894 -90
  555. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +894 -90
  556. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +894 -90
  557. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +894 -90
  558. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +894 -90
  559. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +899 -91
  560. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +894 -90
  561. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +894 -90
  562. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +894 -90
  563. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +894 -90
  564. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +894 -90
  565. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +894 -90
  566. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +894 -90
  567. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +894 -90
  568. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +894 -90
  569. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +894 -90
  570. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +894 -90
  571. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +894 -90
  572. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +894 -90
  573. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/clear-view-button.png +0 -0
  574. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/cleared-view.png +0 -0
  575. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/config-table-columns-to-locations.png +0 -0
  576. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/configure-button.png +0 -0
  577. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/create-saved-view-success.png +0 -0
  578. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/current-saved-view-drop-down-menu.png +0 -0
  579. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/default-location-list-view.png +0 -0
  580. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/dropdown-button-after-new-saved-view.png +0 -0
  581. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-application-to-locations.png +0 -0
  582. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/filter-button.png +0 -0
  583. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/global-default-location-list-view.png +0 -0
  584. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/location-list-view-with-saved-views.png +0 -0
  585. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/navigation-menu.png +0 -0
  586. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-as-new-view-drop-down.png +0 -0
  587. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/save-view-modal.png +0 -0
  588. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-buttons.png +0 -0
  589. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-success.png +0 -0
  590. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view-unchecked.png +0 -0
  591. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-admin-edit-view.png +0 -0
  592. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-different-user.png +0 -0
  593. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/saved-view-modal-unchecked.png +0 -0
  594. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-button.png +0 -0
  595. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/set-as-my-default-success.png +0 -0
  596. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/unsaved-saved-view.png +0 -0
  597. nautobot/project-static/docs/user-guide/feature-guides/images/saved-views/updated-saved-view.png +0 -0
  598. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +894 -90
  599. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +894 -90
  600. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +894 -90
  601. nautobot/project-static/docs/user-guide/index.html +894 -90
  602. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +894 -90
  603. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +894 -90
  604. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +894 -90
  605. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +894 -90
  606. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +1260 -787
  607. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +897 -93
  608. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +894 -90
  609. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +894 -90
  610. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +894 -90
  611. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +894 -90
  612. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +894 -90
  613. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +894 -90
  614. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +894 -90
  615. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +894 -90
  616. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +894 -90
  617. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +898 -90
  618. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +894 -90
  619. nautobot/project-static/docs/user-guide/platform-functionality/note.html +897 -93
  620. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +9061 -0
  621. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +897 -93
  622. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +894 -90
  623. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +894 -90
  624. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +894 -90
  625. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +894 -90
  626. nautobot/project-static/docs/user-guide/platform-functionality/role.html +897 -93
  627. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +9137 -0
  628. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +897 -93
  629. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +8933 -0
  630. nautobot/project-static/docs/user-guide/platform-functionality/status.html +894 -90
  631. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +894 -90
  632. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +952 -123
  633. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +894 -90
  634. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +894 -90
  635. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +894 -90
  636. nautobot/project-static/js/forms.js +71 -0
  637. nautobot/project-static/js/table_sorting_indicator.js +46 -0
  638. nautobot/project-static/js/tableconfig.js +6 -1
  639. nautobot/project-static/materialdesignicons-7.4.47/css/materialdesignicons.min.css +3 -0
  640. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.eot +0 -0
  641. nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/fonts/materialdesignicons-webfont.ttf +0 -0
  642. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff +0 -0
  643. nautobot/project-static/materialdesignicons-7.4.47/fonts/materialdesignicons-webfont.woff2 +0 -0
  644. nautobot/tenancy/__init__.py +0 -1
  645. nautobot/tenancy/apps.py +1 -0
  646. nautobot/tenancy/factory.py +3 -2
  647. nautobot/tenancy/filters/__init__.py +1 -0
  648. nautobot/tenancy/forms.py +1 -1
  649. nautobot/tenancy/templates/tenancy/tenant.html +24 -20
  650. nautobot/tenancy/views.py +11 -10
  651. nautobot/users/__init__.py +0 -1
  652. nautobot/users/api/serializers.py +1 -1
  653. nautobot/users/api/views.py +4 -2
  654. nautobot/users/apps.py +3 -2
  655. nautobot/users/factory.py +3 -3
  656. nautobot/users/migrations/0010_user_default_saved_views.py +20 -0
  657. nautobot/users/models.py +12 -0
  658. nautobot/users/tests/test_filters.py +6 -3
  659. nautobot/users/urls.py +8 -0
  660. nautobot/virtualization/__init__.py +0 -1
  661. nautobot/virtualization/apps.py +1 -0
  662. nautobot/virtualization/filters.py +6 -1
  663. nautobot/virtualization/forms.py +11 -3
  664. nautobot/virtualization/graphql/types.py +2 -2
  665. nautobot/virtualization/migrations/0029_add_role_field_to_interface_models.py +27 -0
  666. nautobot/virtualization/migrations/0030_alter_virtualmachine_local_config_context_data_owner_content_type_and_more.py +67 -0
  667. nautobot/virtualization/models.py +0 -2
  668. nautobot/virtualization/tables.py +12 -8
  669. nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -1
  670. nautobot/virtualization/templates/virtualization/vminterface.html +7 -1
  671. nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
  672. nautobot/virtualization/tests/test_api.py +9 -4
  673. nautobot/virtualization/tests/test_filters.py +22 -0
  674. nautobot/virtualization/tests/test_models.py +7 -3
  675. nautobot/virtualization/tests/test_views.py +19 -3
  676. nautobot/virtualization/urls.py +2 -2
  677. nautobot/virtualization/views.py +10 -32
  678. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/METADATA +21 -19
  679. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/RECORD +684 -564
  680. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css +0 -1
  681. nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css.map +0 -1
  682. nautobot/project-static/materialdesignicons-6.5.95/.github/ISSUE_TEMPLATE.md +0 -3
  683. nautobot/project-static/materialdesignicons-6.5.95/README.md +0 -25
  684. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css +0 -26654
  685. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.css.map +0 -16
  686. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css +0 -3
  687. nautobot/project-static/materialdesignicons-6.5.95/css/materialdesignicons.min.css.map +0 -16
  688. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff +0 -0
  689. nautobot/project-static/materialdesignicons-6.5.95/fonts/materialdesignicons-webfont.woff2 +0 -0
  690. nautobot/project-static/materialdesignicons-6.5.95/package.json +0 -28
  691. nautobot/project-static/materialdesignicons-6.5.95/preview.html +0 -717
  692. nautobot/project-static/materialdesignicons-6.5.95/scss/_animated.scss +0 -27
  693. nautobot/project-static/materialdesignicons-6.5.95/scss/_core.scss +0 -10
  694. nautobot/project-static/materialdesignicons-6.5.95/scss/_extras.scss +0 -65
  695. nautobot/project-static/materialdesignicons-6.5.95/scss/_functions.scss +0 -20
  696. nautobot/project-static/materialdesignicons-6.5.95/scss/_icons.scss +0 -10
  697. nautobot/project-static/materialdesignicons-6.5.95/scss/_path.scss +0 -10
  698. nautobot/project-static/materialdesignicons-6.5.95/scss/_variables.scss +0 -6606
  699. nautobot/project-static/materialdesignicons-6.5.95/scss/materialdesignicons.scss +0 -8
  700. /nautobot/project-static/{materialdesignicons-6.5.95 → materialdesignicons-7.4.47}/LICENSE +0 -0
  701. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/LICENSE.txt +0 -0
  702. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/NOTICE +0 -0
  703. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/WHEEL +0 -0
  704. {nautobot-2.2.8.dist-info → nautobot-2.3.0.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@
18
18
 
19
19
 
20
20
  <link rel="icon" href="../../assets/favicon.ico">
21
- <meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.29">
21
+ <meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.31">
22
22
 
23
23
 
24
24
 
@@ -26,7 +26,7 @@
26
26
 
27
27
 
28
28
 
29
- <link rel="stylesheet" href="../../assets/stylesheets/main.76a95c52.min.css">
29
+ <link rel="stylesheet" href="../../assets/stylesheets/main.3cba04c6.min.css">
30
30
 
31
31
 
32
32
  <link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
@@ -38,7 +38,7 @@
38
38
 
39
39
 
40
40
 
41
- <style>:root{--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M288 0H128c-17.7 0-32 14.3-32 32s14.3 32 32 32v132.8c0 11.8-3.3 23.5-9.5 33.5L10.3 406.2C3.6 417.2 0 429.7 0 442.6 0 480.9 31.1 512 69.4 512h309.2c38.3 0 69.4-31.1 69.4-69.4 0-12.8-3.6-25.4-10.3-36.4L329.5 230.4c-6.2-10.1-9.5-21.7-9.5-33.5V64c17.7 0 32-14.3 32-32S337.7 0 320 0h-32zm-96 196.8V64h64v132.8c0 23.7 6.6 46.9 19 67.1l34.5 56.1h-171l34.5-56.1c12.4-20.2 19-43.4 19-67.1z"/></svg>');}</style>
41
+ <style>:root{--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M288 0H128c-17.7 0-32 14.3-32 32s14.3 32 32 32v132.8c0 11.8-3.3 23.5-9.5 33.5L10.3 406.2C3.6 417.2 0 429.7 0 442.6 0 480.9 31.1 512 69.4 512h309.2c38.3 0 69.4-31.1 69.4-69.4 0-12.8-3.6-25.4-10.3-36.4L329.5 230.4c-6.2-10.1-9.5-21.7-9.5-33.5V64c17.7 0 32-14.3 32-32S337.7 0 320 0h-32zm-96 196.8V64h64v132.8c0 23.7 6.6 46.9 19 67.1l34.5 56.1h-171l34.5-56.1c12.4-20.2 19-43.4 19-67.1z"/></svg>');}</style>
42
42
 
43
43
 
44
44
 
@@ -217,7 +217,7 @@
217
217
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
218
218
  <div class="md-source__icon md-icon">
219
219
 
220
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
220
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
221
221
  </div>
222
222
  <div class="md-source__repository">
223
223
  GitHub
@@ -238,7 +238,7 @@
238
238
 
239
239
 
240
240
  <li class="md-tabs__item">
241
- <a href="../../overview/index.html" class="md-tabs__link">
241
+ <a href="../../index.html" class="md-tabs__link">
242
242
 
243
243
 
244
244
 
@@ -377,7 +377,7 @@
377
377
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
378
378
  <div class="md-source__icon md-icon">
379
379
 
380
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
380
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
381
381
  </div>
382
382
  <div class="md-source__repository">
383
383
  GitHub
@@ -409,7 +409,7 @@
409
409
 
410
410
 
411
411
  <div class="md-nav__link md-nav__container">
412
- <a href="../../overview/index.html" class="md-nav__link ">
412
+ <a href="../../index.html" class="md-nav__link ">
413
413
 
414
414
 
415
415
  <span class="md-ellipsis">
@@ -2484,23 +2484,702 @@
2484
2484
  <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_3" >
2485
2485
 
2486
2486
 
2487
- <label class="md-nav__link" for="__nav_2_3_3" id="__nav_2_3_3_label" tabindex="0">
2487
+
2488
+ <div class="md-nav__link md-nav__container">
2489
+ <a href="../../user-guide/core-data-model/cloud/cloud.html" class="md-nav__link ">
2490
+
2491
+
2492
+ <span class="md-ellipsis">
2493
+ Cloud
2494
+ </span>
2495
+
2496
+
2497
+ </a>
2498
+
2499
+
2500
+ <label class="md-nav__link " for="__nav_2_3_3" id="__nav_2_3_3_label" tabindex="0">
2501
+ <span class="md-nav__icon md-icon"></span>
2502
+ </label>
2503
+
2504
+ </div>
2505
+
2506
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_3_label" aria-expanded="false">
2507
+ <label class="md-nav__title" for="__nav_2_3_3">
2508
+ <span class="md-nav__icon md-icon"></span>
2509
+ Cloud
2510
+ </label>
2511
+ <ul class="md-nav__list" data-md-scrollfix>
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+ <li class="md-nav__item">
2520
+ <a href="../../user-guide/core-data-model/cloud/cloudaccount.html" class="md-nav__link">
2521
+
2522
+
2523
+ <span class="md-ellipsis">
2524
+ Cloud Account
2525
+ </span>
2526
+
2527
+
2528
+ </a>
2529
+ </li>
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+
2538
+
2539
+
2540
+ <li class="md-nav__item">
2541
+ <a href="../../user-guide/core-data-model/cloud/cloudnetwork.html" class="md-nav__link">
2542
+
2543
+
2544
+ <span class="md-ellipsis">
2545
+ Cloud Network
2546
+ </span>
2547
+
2548
+
2549
+ </a>
2550
+ </li>
2551
+
2552
+
2553
+
2554
+
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+ <li class="md-nav__item">
2562
+ <a href="../../user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html" class="md-nav__link">
2563
+
2564
+
2565
+ <span class="md-ellipsis">
2566
+ Cloud Network Prefix Assignment
2567
+ </span>
2568
+
2569
+
2570
+ </a>
2571
+ </li>
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+ <li class="md-nav__item">
2583
+ <a href="../../user-guide/core-data-model/cloud/cloudresourcetype.html" class="md-nav__link">
2584
+
2585
+
2586
+ <span class="md-ellipsis">
2587
+ Cloud Resource Type
2588
+ </span>
2589
+
2590
+
2591
+ </a>
2592
+ </li>
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+ <li class="md-nav__item">
2604
+ <a href="../../user-guide/core-data-model/cloud/cloudservice.html" class="md-nav__link">
2605
+
2606
+
2607
+ <span class="md-ellipsis">
2608
+ Cloud Service
2609
+ </span>
2610
+
2611
+
2612
+ </a>
2613
+ </li>
2614
+
2615
+
2616
+
2617
+
2618
+
2619
+
2620
+
2621
+
2622
+
2623
+
2624
+ <li class="md-nav__item">
2625
+ <a href="../../user-guide/core-data-model/cloud/cloudservicenetworkassignment.html" class="md-nav__link">
2626
+
2627
+
2628
+ <span class="md-ellipsis">
2629
+ Cloud Service Network Assignment
2630
+ </span>
2631
+
2632
+
2633
+ </a>
2634
+ </li>
2635
+
2636
+
2637
+
2638
+
2639
+ </ul>
2640
+ </nav>
2641
+
2642
+ </li>
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+ <li class="md-nav__item md-nav__item--nested">
2661
+
2662
+
2663
+
2664
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4" >
2665
+
2666
+
2667
+ <label class="md-nav__link" for="__nav_2_3_4" id="__nav_2_3_4_label" tabindex="0">
2668
+
2669
+
2670
+ <span class="md-ellipsis">
2671
+ DCIM
2672
+ </span>
2673
+
2674
+
2675
+ <span class="md-nav__icon md-icon"></span>
2676
+ </label>
2677
+
2678
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_4_label" aria-expanded="false">
2679
+ <label class="md-nav__title" for="__nav_2_3_4">
2680
+ <span class="md-nav__icon md-icon"></span>
2681
+ DCIM
2682
+ </label>
2683
+ <ul class="md-nav__list" data-md-scrollfix>
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+ <li class="md-nav__item">
2692
+ <a href="../../user-guide/core-data-model/dcim/locationtype.html" class="md-nav__link">
2693
+
2694
+
2695
+ <span class="md-ellipsis">
2696
+ Location Type
2697
+ </span>
2698
+
2699
+
2700
+ </a>
2701
+ </li>
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+ <li class="md-nav__item">
2713
+ <a href="../../user-guide/core-data-model/dcim/location.html" class="md-nav__link">
2714
+
2715
+
2716
+ <span class="md-ellipsis">
2717
+ Location
2718
+ </span>
2719
+
2720
+
2721
+ </a>
2722
+ </li>
2723
+
2724
+
2725
+
2726
+
2727
+
2728
+
2729
+
2730
+
2731
+
2732
+
2733
+ <li class="md-nav__item">
2734
+ <a href="../../user-guide/core-data-model/dcim/rackgroup.html" class="md-nav__link">
2735
+
2736
+
2737
+ <span class="md-ellipsis">
2738
+ Rack Group
2739
+ </span>
2740
+
2741
+
2742
+ </a>
2743
+ </li>
2744
+
2745
+
2746
+
2747
+
2748
+
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+ <li class="md-nav__item">
2755
+ <a href="../../user-guide/core-data-model/dcim/rack.html" class="md-nav__link">
2756
+
2757
+
2758
+ <span class="md-ellipsis">
2759
+ Rack
2760
+ </span>
2761
+
2762
+
2763
+ </a>
2764
+ </li>
2765
+
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+ <li class="md-nav__item">
2776
+ <a href="../../user-guide/core-data-model/dcim/manufacturer.html" class="md-nav__link">
2777
+
2778
+
2779
+ <span class="md-ellipsis">
2780
+ Manufacturer
2781
+ </span>
2782
+
2783
+
2784
+ </a>
2785
+ </li>
2786
+
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+ <li class="md-nav__item">
2797
+ <a href="../../user-guide/core-data-model/dcim/devicefamily.html" class="md-nav__link">
2798
+
2799
+
2800
+ <span class="md-ellipsis">
2801
+ Device Family
2802
+ </span>
2803
+
2804
+
2805
+ </a>
2806
+ </li>
2807
+
2808
+
2809
+
2810
+
2811
+
2812
+
2813
+
2814
+
2815
+
2816
+
2817
+ <li class="md-nav__item">
2818
+ <a href="../../user-guide/core-data-model/dcim/platform.html" class="md-nav__link">
2819
+
2820
+
2821
+ <span class="md-ellipsis">
2822
+ Platform
2823
+ </span>
2824
+
2825
+
2826
+ </a>
2827
+ </li>
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+ <li class="md-nav__item md-nav__item--nested">
2846
+
2847
+
2848
+
2849
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4_8" >
2850
+
2851
+
2852
+
2853
+ <div class="md-nav__link md-nav__container">
2854
+ <a href="../../user-guide/core-data-model/dcim/devicetype.html" class="md-nav__link ">
2855
+
2856
+
2857
+ <span class="md-ellipsis">
2858
+ Device Type
2859
+ </span>
2860
+
2861
+
2862
+ </a>
2863
+
2864
+
2865
+ <label class="md-nav__link " for="__nav_2_3_4_8" id="__nav_2_3_4_8_label" tabindex="0">
2866
+ <span class="md-nav__icon md-icon"></span>
2867
+ </label>
2868
+
2869
+ </div>
2870
+
2871
+ <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_4_8_label" aria-expanded="false">
2872
+ <label class="md-nav__title" for="__nav_2_3_4_8">
2873
+ <span class="md-nav__icon md-icon"></span>
2874
+ Device Type
2875
+ </label>
2876
+ <ul class="md-nav__list" data-md-scrollfix>
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+ <li class="md-nav__item">
2885
+ <a href="../../user-guide/core-data-model/dcim/consoleporttemplate.html" class="md-nav__link">
2886
+
2887
+
2888
+ <span class="md-ellipsis">
2889
+ Console Port Template
2890
+ </span>
2891
+
2892
+
2893
+ </a>
2894
+ </li>
2895
+
2896
+
2897
+
2898
+
2899
+
2900
+
2901
+
2902
+
2903
+
2904
+
2905
+ <li class="md-nav__item">
2906
+ <a href="../../user-guide/core-data-model/dcim/consoleserverporttemplate.html" class="md-nav__link">
2907
+
2908
+
2909
+ <span class="md-ellipsis">
2910
+ Console Server Port Template
2911
+ </span>
2912
+
2913
+
2914
+ </a>
2915
+ </li>
2916
+
2917
+
2918
+
2919
+
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+ <li class="md-nav__item">
2927
+ <a href="../../user-guide/core-data-model/dcim/devicebaytemplate.html" class="md-nav__link">
2928
+
2929
+
2930
+ <span class="md-ellipsis">
2931
+ Device Bay Template
2932
+ </span>
2933
+
2934
+
2935
+ </a>
2936
+ </li>
2937
+
2938
+
2939
+
2940
+
2941
+
2942
+
2943
+
2944
+
2945
+
2946
+
2947
+ <li class="md-nav__item">
2948
+ <a href="../../user-guide/core-data-model/dcim/frontporttemplate.html" class="md-nav__link">
2949
+
2950
+
2951
+ <span class="md-ellipsis">
2952
+ Front Port Template
2953
+ </span>
2954
+
2955
+
2956
+ </a>
2957
+ </li>
2958
+
2959
+
2960
+
2961
+
2962
+
2963
+
2964
+
2965
+
2966
+
2967
+
2968
+ <li class="md-nav__item">
2969
+ <a href="../../user-guide/core-data-model/dcim/interfacetemplate.html" class="md-nav__link">
2970
+
2971
+
2972
+ <span class="md-ellipsis">
2973
+ Interface Template
2974
+ </span>
2975
+
2976
+
2977
+ </a>
2978
+ </li>
2979
+
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+ <li class="md-nav__item">
2990
+ <a href="../../user-guide/core-data-model/dcim/modulebaytemplate.html" class="md-nav__link">
2991
+
2992
+
2993
+ <span class="md-ellipsis">
2994
+ Module Bay Template
2995
+ </span>
2996
+
2997
+
2998
+ </a>
2999
+ </li>
3000
+
3001
+
3002
+
3003
+
3004
+
3005
+
3006
+
3007
+
3008
+
3009
+
3010
+ <li class="md-nav__item">
3011
+ <a href="../../user-guide/core-data-model/dcim/poweroutlettemplate.html" class="md-nav__link">
3012
+
3013
+
3014
+ <span class="md-ellipsis">
3015
+ Power Outlet Template
3016
+ </span>
3017
+
3018
+
3019
+ </a>
3020
+ </li>
3021
+
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+ <li class="md-nav__item">
3032
+ <a href="../../user-guide/core-data-model/dcim/powerporttemplate.html" class="md-nav__link">
3033
+
3034
+
3035
+ <span class="md-ellipsis">
3036
+ Power Port Template
3037
+ </span>
3038
+
3039
+
3040
+ </a>
3041
+ </li>
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+ <li class="md-nav__item">
3053
+ <a href="../../user-guide/core-data-model/dcim/rearporttemplate.html" class="md-nav__link">
3054
+
3055
+
3056
+ <span class="md-ellipsis">
3057
+ Rear Port Template
3058
+ </span>
3059
+
3060
+
3061
+ </a>
3062
+ </li>
3063
+
3064
+
3065
+
3066
+
3067
+ </ul>
3068
+ </nav>
3069
+
3070
+ </li>
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+
3087
+
3088
+ <li class="md-nav__item md-nav__item--nested">
3089
+
3090
+
3091
+
3092
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4_9" >
3093
+
3094
+
3095
+
3096
+ <div class="md-nav__link md-nav__container">
3097
+ <a href="../../user-guide/core-data-model/dcim/device.html" class="md-nav__link ">
3098
+
3099
+
3100
+ <span class="md-ellipsis">
3101
+ Device
3102
+ </span>
3103
+
3104
+
3105
+ </a>
3106
+
3107
+
3108
+ <label class="md-nav__link " for="__nav_2_3_4_9" id="__nav_2_3_4_9_label" tabindex="0">
3109
+ <span class="md-nav__icon md-icon"></span>
3110
+ </label>
3111
+
3112
+ </div>
3113
+
3114
+ <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_4_9_label" aria-expanded="false">
3115
+ <label class="md-nav__title" for="__nav_2_3_4_9">
3116
+ <span class="md-nav__icon md-icon"></span>
3117
+ Device
3118
+ </label>
3119
+ <ul class="md-nav__list" data-md-scrollfix>
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+
3127
+ <li class="md-nav__item">
3128
+ <a href="../../user-guide/core-data-model/dcim/consoleport.html" class="md-nav__link">
3129
+
3130
+
3131
+ <span class="md-ellipsis">
3132
+ Console Port
3133
+ </span>
3134
+
3135
+
3136
+ </a>
3137
+ </li>
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+ <li class="md-nav__item">
3149
+ <a href="../../user-guide/core-data-model/dcim/consoleserverport.html" class="md-nav__link">
3150
+
3151
+
3152
+ <span class="md-ellipsis">
3153
+ Console Server Port
3154
+ </span>
3155
+
3156
+
3157
+ </a>
3158
+ </li>
3159
+
3160
+
3161
+
2488
3162
 
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+ <li class="md-nav__item">
3170
+ <a href="../../user-guide/core-data-model/dcim/devicebay.html" class="md-nav__link">
3171
+
2489
3172
 
2490
3173
  <span class="md-ellipsis">
2491
- DCIM
3174
+ Device Bay
2492
3175
  </span>
2493
3176
 
2494
3177
 
2495
- <span class="md-nav__icon md-icon"></span>
2496
- </label>
2497
-
2498
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_3_label" aria-expanded="false">
2499
- <label class="md-nav__title" for="__nav_2_3_3">
2500
- <span class="md-nav__icon md-icon"></span>
2501
- DCIM
2502
- </label>
2503
- <ul class="md-nav__list" data-md-scrollfix>
3178
+ </a>
3179
+ </li>
3180
+
3181
+
3182
+
2504
3183
 
2505
3184
 
2506
3185
 
@@ -2509,11 +3188,11 @@
2509
3188
 
2510
3189
 
2511
3190
  <li class="md-nav__item">
2512
- <a href="../../user-guide/core-data-model/dcim/locationtype.html" class="md-nav__link">
3191
+ <a href="../../user-guide/core-data-model/dcim/frontport.html" class="md-nav__link">
2513
3192
 
2514
3193
 
2515
3194
  <span class="md-ellipsis">
2516
- Location Type
3195
+ Front Port
2517
3196
  </span>
2518
3197
 
2519
3198
 
@@ -2530,11 +3209,11 @@
2530
3209
 
2531
3210
 
2532
3211
  <li class="md-nav__item">
2533
- <a href="../../user-guide/core-data-model/dcim/location.html" class="md-nav__link">
3212
+ <a href="../../user-guide/core-data-model/dcim/interface.html" class="md-nav__link">
2534
3213
 
2535
3214
 
2536
3215
  <span class="md-ellipsis">
2537
- Location
3216
+ Interface
2538
3217
  </span>
2539
3218
 
2540
3219
 
@@ -2551,11 +3230,11 @@
2551
3230
 
2552
3231
 
2553
3232
  <li class="md-nav__item">
2554
- <a href="../../user-guide/core-data-model/dcim/rackgroup.html" class="md-nav__link">
3233
+ <a href="../../user-guide/core-data-model/dcim/inventoryitem.html" class="md-nav__link">
2555
3234
 
2556
3235
 
2557
3236
  <span class="md-ellipsis">
2558
- Rack Group
3237
+ Inventory Item
2559
3238
  </span>
2560
3239
 
2561
3240
 
@@ -2572,11 +3251,11 @@
2572
3251
 
2573
3252
 
2574
3253
  <li class="md-nav__item">
2575
- <a href="../../user-guide/core-data-model/dcim/rack.html" class="md-nav__link">
3254
+ <a href="../../user-guide/core-data-model/dcim/modulebay.html" class="md-nav__link">
2576
3255
 
2577
3256
 
2578
3257
  <span class="md-ellipsis">
2579
- Rack
3258
+ Module Bay
2580
3259
  </span>
2581
3260
 
2582
3261
 
@@ -2593,11 +3272,11 @@
2593
3272
 
2594
3273
 
2595
3274
  <li class="md-nav__item">
2596
- <a href="../../user-guide/core-data-model/dcim/manufacturer.html" class="md-nav__link">
3275
+ <a href="../../user-guide/core-data-model/dcim/powerport.html" class="md-nav__link">
2597
3276
 
2598
3277
 
2599
3278
  <span class="md-ellipsis">
2600
- Manufacturer
3279
+ Power Port
2601
3280
  </span>
2602
3281
 
2603
3282
 
@@ -2614,11 +3293,11 @@
2614
3293
 
2615
3294
 
2616
3295
  <li class="md-nav__item">
2617
- <a href="../../user-guide/core-data-model/dcim/devicefamily.html" class="md-nav__link">
3296
+ <a href="../../user-guide/core-data-model/dcim/poweroutlet.html" class="md-nav__link">
2618
3297
 
2619
3298
 
2620
3299
  <span class="md-ellipsis">
2621
- Device Family
3300
+ Power Outlet
2622
3301
  </span>
2623
3302
 
2624
3303
 
@@ -2635,11 +3314,11 @@
2635
3314
 
2636
3315
 
2637
3316
  <li class="md-nav__item">
2638
- <a href="../../user-guide/core-data-model/dcim/platform.html" class="md-nav__link">
3317
+ <a href="../../user-guide/core-data-model/dcim/rearport.html" class="md-nav__link">
2639
3318
 
2640
3319
 
2641
3320
  <span class="md-ellipsis">
2642
- Platform
3321
+ Rear Port
2643
3322
  </span>
2644
3323
 
2645
3324
 
@@ -2649,6 +3328,14 @@
2649
3328
 
2650
3329
 
2651
3330
 
3331
+ </ul>
3332
+ </nav>
3333
+
3334
+ </li>
3335
+
3336
+
3337
+
3338
+
2652
3339
 
2653
3340
 
2654
3341
 
@@ -2666,32 +3353,32 @@
2666
3353
 
2667
3354
 
2668
3355
 
2669
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_3_8" >
3356
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4_10" >
2670
3357
 
2671
3358
 
2672
3359
 
2673
3360
  <div class="md-nav__link md-nav__container">
2674
- <a href="../../user-guide/core-data-model/dcim/devicetype.html" class="md-nav__link ">
3361
+ <a href="../../user-guide/core-data-model/dcim/moduletype.html" class="md-nav__link ">
2675
3362
 
2676
3363
 
2677
3364
  <span class="md-ellipsis">
2678
- Device Type
3365
+ Module Type
2679
3366
  </span>
2680
3367
 
2681
3368
 
2682
3369
  </a>
2683
3370
 
2684
3371
 
2685
- <label class="md-nav__link " for="__nav_2_3_3_8" id="__nav_2_3_3_8_label" tabindex="0">
3372
+ <label class="md-nav__link " for="__nav_2_3_4_10" id="__nav_2_3_4_10_label" tabindex="0">
2686
3373
  <span class="md-nav__icon md-icon"></span>
2687
3374
  </label>
2688
3375
 
2689
3376
  </div>
2690
3377
 
2691
- <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_3_8_label" aria-expanded="false">
2692
- <label class="md-nav__title" for="__nav_2_3_3_8">
3378
+ <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_4_10_label" aria-expanded="false">
3379
+ <label class="md-nav__title" for="__nav_2_3_4_10">
2693
3380
  <span class="md-nav__icon md-icon"></span>
2694
- Device Type
3381
+ Module Type
2695
3382
  </label>
2696
3383
  <ul class="md-nav__list" data-md-scrollfix>
2697
3384
 
@@ -2744,11 +3431,11 @@
2744
3431
 
2745
3432
 
2746
3433
  <li class="md-nav__item">
2747
- <a href="../../user-guide/core-data-model/dcim/devicebaytemplate.html" class="md-nav__link">
3434
+ <a href="../../user-guide/core-data-model/dcim/frontporttemplate.html" class="md-nav__link">
2748
3435
 
2749
3436
 
2750
3437
  <span class="md-ellipsis">
2751
- Device Bay Template
3438
+ Front Port Template
2752
3439
  </span>
2753
3440
 
2754
3441
 
@@ -2765,11 +3452,11 @@
2765
3452
 
2766
3453
 
2767
3454
  <li class="md-nav__item">
2768
- <a href="../../user-guide/core-data-model/dcim/frontporttemplate.html" class="md-nav__link">
3455
+ <a href="../../user-guide/core-data-model/dcim/interfacetemplate.html" class="md-nav__link">
2769
3456
 
2770
3457
 
2771
3458
  <span class="md-ellipsis">
2772
- Front Port Template
3459
+ Interface Template
2773
3460
  </span>
2774
3461
 
2775
3462
 
@@ -2786,11 +3473,11 @@
2786
3473
 
2787
3474
 
2788
3475
  <li class="md-nav__item">
2789
- <a href="../../user-guide/core-data-model/dcim/interfacetemplate.html" class="md-nav__link">
3476
+ <a href="../../user-guide/core-data-model/dcim/modulebaytemplate.html" class="md-nav__link">
2790
3477
 
2791
3478
 
2792
3479
  <span class="md-ellipsis">
2793
- Interface Template
3480
+ Module Bay Template
2794
3481
  </span>
2795
3482
 
2796
3483
 
@@ -2888,32 +3575,32 @@
2888
3575
 
2889
3576
 
2890
3577
 
2891
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_3_9" >
3578
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4_11" >
2892
3579
 
2893
3580
 
2894
3581
 
2895
3582
  <div class="md-nav__link md-nav__container">
2896
- <a href="../../user-guide/core-data-model/dcim/device.html" class="md-nav__link ">
3583
+ <a href="../../user-guide/core-data-model/dcim/module.html" class="md-nav__link ">
2897
3584
 
2898
3585
 
2899
3586
  <span class="md-ellipsis">
2900
- Device
3587
+ Module
2901
3588
  </span>
2902
3589
 
2903
3590
 
2904
3591
  </a>
2905
3592
 
2906
3593
 
2907
- <label class="md-nav__link " for="__nav_2_3_3_9" id="__nav_2_3_3_9_label" tabindex="0">
3594
+ <label class="md-nav__link " for="__nav_2_3_4_11" id="__nav_2_3_4_11_label" tabindex="0">
2908
3595
  <span class="md-nav__icon md-icon"></span>
2909
3596
  </label>
2910
3597
 
2911
3598
  </div>
2912
3599
 
2913
- <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_3_9_label" aria-expanded="false">
2914
- <label class="md-nav__title" for="__nav_2_3_3_9">
3600
+ <nav class="md-nav" data-md-level="4" aria-labelledby="__nav_2_3_4_11_label" aria-expanded="false">
3601
+ <label class="md-nav__title" for="__nav_2_3_4_11">
2915
3602
  <span class="md-nav__icon md-icon"></span>
2916
- Device
3603
+ Module
2917
3604
  </label>
2918
3605
  <ul class="md-nav__list" data-md-scrollfix>
2919
3606
 
@@ -2966,11 +3653,11 @@
2966
3653
 
2967
3654
 
2968
3655
  <li class="md-nav__item">
2969
- <a href="../../user-guide/core-data-model/dcim/devicebay.html" class="md-nav__link">
3656
+ <a href="../../user-guide/core-data-model/dcim/frontport.html" class="md-nav__link">
2970
3657
 
2971
3658
 
2972
3659
  <span class="md-ellipsis">
2973
- Device Bay
3660
+ Front Port
2974
3661
  </span>
2975
3662
 
2976
3663
 
@@ -2987,11 +3674,11 @@
2987
3674
 
2988
3675
 
2989
3676
  <li class="md-nav__item">
2990
- <a href="../../user-guide/core-data-model/dcim/frontport.html" class="md-nav__link">
3677
+ <a href="../../user-guide/core-data-model/dcim/interface.html" class="md-nav__link">
2991
3678
 
2992
3679
 
2993
3680
  <span class="md-ellipsis">
2994
- Front Port
3681
+ Interface
2995
3682
  </span>
2996
3683
 
2997
3684
 
@@ -3008,11 +3695,11 @@
3008
3695
 
3009
3696
 
3010
3697
  <li class="md-nav__item">
3011
- <a href="../../user-guide/core-data-model/dcim/interface.html" class="md-nav__link">
3698
+ <a href="../../user-guide/core-data-model/dcim/inventoryitem.html" class="md-nav__link">
3012
3699
 
3013
3700
 
3014
3701
  <span class="md-ellipsis">
3015
- Interface
3702
+ Inventory Item
3016
3703
  </span>
3017
3704
 
3018
3705
 
@@ -3029,11 +3716,11 @@
3029
3716
 
3030
3717
 
3031
3718
  <li class="md-nav__item">
3032
- <a href="../../user-guide/core-data-model/dcim/inventoryitem.html" class="md-nav__link">
3719
+ <a href="../../user-guide/core-data-model/dcim/modulebay.html" class="md-nav__link">
3033
3720
 
3034
3721
 
3035
3722
  <span class="md-ellipsis">
3036
- Inventory Item
3723
+ Module Bay
3037
3724
  </span>
3038
3725
 
3039
3726
 
@@ -3370,10 +4057,10 @@
3370
4057
 
3371
4058
 
3372
4059
 
3373
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_4" >
4060
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_5" >
3374
4061
 
3375
4062
 
3376
- <label class="md-nav__link" for="__nav_2_3_4" id="__nav_2_3_4_label" tabindex="0">
4063
+ <label class="md-nav__link" for="__nav_2_3_5" id="__nav_2_3_5_label" tabindex="0">
3377
4064
 
3378
4065
 
3379
4066
  <span class="md-ellipsis">
@@ -3384,8 +4071,8 @@
3384
4071
  <span class="md-nav__icon md-icon"></span>
3385
4072
  </label>
3386
4073
 
3387
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_4_label" aria-expanded="false">
3388
- <label class="md-nav__title" for="__nav_2_3_4">
4074
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_5_label" aria-expanded="false">
4075
+ <label class="md-nav__title" for="__nav_2_3_5">
3389
4076
  <span class="md-nav__icon md-icon"></span>
3390
4077
  Extras
3391
4078
  </label>
@@ -3500,10 +4187,10 @@
3500
4187
 
3501
4188
 
3502
4189
 
3503
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_5" >
4190
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_6" >
3504
4191
 
3505
4192
 
3506
- <label class="md-nav__link" for="__nav_2_3_5" id="__nav_2_3_5_label" tabindex="0">
4193
+ <label class="md-nav__link" for="__nav_2_3_6" id="__nav_2_3_6_label" tabindex="0">
3507
4194
 
3508
4195
 
3509
4196
  <span class="md-ellipsis">
@@ -3514,8 +4201,8 @@
3514
4201
  <span class="md-nav__icon md-icon"></span>
3515
4202
  </label>
3516
4203
 
3517
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_5_label" aria-expanded="false">
3518
- <label class="md-nav__title" for="__nav_2_3_5">
4204
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_6_label" aria-expanded="false">
4205
+ <label class="md-nav__title" for="__nav_2_3_6">
3519
4206
  <span class="md-nav__icon md-icon"></span>
3520
4207
  IPAM
3521
4208
  </label>
@@ -3735,10 +4422,10 @@
3735
4422
 
3736
4423
 
3737
4424
 
3738
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_6" >
4425
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_7" >
3739
4426
 
3740
4427
 
3741
- <label class="md-nav__link" for="__nav_2_3_6" id="__nav_2_3_6_label" tabindex="0">
4428
+ <label class="md-nav__link" for="__nav_2_3_7" id="__nav_2_3_7_label" tabindex="0">
3742
4429
 
3743
4430
 
3744
4431
  <span class="md-ellipsis">
@@ -3749,8 +4436,8 @@
3749
4436
  <span class="md-nav__icon md-icon"></span>
3750
4437
  </label>
3751
4438
 
3752
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_6_label" aria-expanded="false">
3753
- <label class="md-nav__title" for="__nav_2_3_6">
4439
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_7_label" aria-expanded="false">
4440
+ <label class="md-nav__title" for="__nav_2_3_7">
3754
4441
  <span class="md-nav__icon md-icon"></span>
3755
4442
  Tenancy
3756
4443
  </label>
@@ -3823,10 +4510,10 @@
3823
4510
 
3824
4511
 
3825
4512
 
3826
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_7" >
4513
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3_8" >
3827
4514
 
3828
4515
 
3829
- <label class="md-nav__link" for="__nav_2_3_7" id="__nav_2_3_7_label" tabindex="0">
4516
+ <label class="md-nav__link" for="__nav_2_3_8" id="__nav_2_3_8_label" tabindex="0">
3830
4517
 
3831
4518
 
3832
4519
  <span class="md-ellipsis">
@@ -3837,8 +4524,8 @@
3837
4524
  <span class="md-nav__icon md-icon"></span>
3838
4525
  </label>
3839
4526
 
3840
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_7_label" aria-expanded="false">
3841
- <label class="md-nav__title" for="__nav_2_3_7">
4527
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_3_8_label" aria-expanded="false">
4528
+ <label class="md-nav__title" for="__nav_2_3_8">
3842
4529
  <span class="md-nav__icon md-icon"></span>
3843
4530
  Virtualization
3844
4531
  </label>
@@ -4093,21 +4780,75 @@
4093
4780
 
4094
4781
 
4095
4782
 
4096
- <li class="md-nav__item">
4097
- <a href="../../user-guide/platform-functionality/dynamicgroup.html" class="md-nav__link">
4783
+
4784
+
4785
+
4786
+
4787
+
4788
+
4789
+
4790
+ <li class="md-nav__item md-nav__item--nested">
4791
+
4792
+
4098
4793
 
4794
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_5" >
4795
+
4796
+
4797
+
4798
+ <div class="md-nav__link md-nav__container">
4799
+ <a href="../../user-guide/platform-functionality/dynamicgroup.html" class="md-nav__link ">
4800
+
4099
4801
 
4100
4802
  <span class="md-ellipsis">
4101
4803
  Dynamic Groups
4102
4804
  </span>
4103
4805
 
4104
4806
 
4807
+ </a>
4808
+
4809
+
4810
+ <label class="md-nav__link " for="__nav_2_4_5" id="__nav_2_4_5_label" tabindex="0">
4811
+ <span class="md-nav__icon md-icon"></span>
4812
+ </label>
4813
+
4814
+ </div>
4815
+
4816
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_5_label" aria-expanded="false">
4817
+ <label class="md-nav__title" for="__nav_2_4_5">
4818
+ <span class="md-nav__icon md-icon"></span>
4819
+ Dynamic Groups
4820
+ </label>
4821
+ <ul class="md-nav__list" data-md-scrollfix>
4822
+
4823
+
4824
+
4825
+
4826
+
4827
+
4828
+
4829
+ <li class="md-nav__item">
4830
+ <a href="../../user-guide/platform-functionality/staticgroupassociation.html" class="md-nav__link">
4831
+
4832
+
4833
+ <span class="md-ellipsis">
4834
+ Static Group Associations
4835
+ </span>
4836
+
4837
+
4105
4838
  </a>
4106
4839
  </li>
4107
4840
 
4108
4841
 
4109
4842
 
4110
4843
 
4844
+ </ul>
4845
+ </nav>
4846
+
4847
+ </li>
4848
+
4849
+
4850
+
4851
+
4111
4852
 
4112
4853
 
4113
4854
 
@@ -4453,6 +5194,27 @@
4453
5194
 
4454
5195
 
4455
5196
 
5197
+ <li class="md-nav__item">
5198
+ <a href="../../user-guide/platform-functionality/objectmetadata.html" class="md-nav__link">
5199
+
5200
+
5201
+ <span class="md-ellipsis">
5202
+ Object Metadata
5203
+ </span>
5204
+
5205
+
5206
+ </a>
5207
+ </li>
5208
+
5209
+
5210
+
5211
+
5212
+
5213
+
5214
+
5215
+
5216
+
5217
+
4456
5218
  <li class="md-nav__item">
4457
5219
  <a href="../../user-guide/platform-functionality/relationship.html" class="md-nav__link">
4458
5220
 
@@ -4485,7 +5247,7 @@
4485
5247
 
4486
5248
 
4487
5249
 
4488
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_15" >
5250
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_16" >
4489
5251
 
4490
5252
 
4491
5253
 
@@ -4501,14 +5263,14 @@
4501
5263
  </a>
4502
5264
 
4503
5265
 
4504
- <label class="md-nav__link " for="__nav_2_4_15" id="__nav_2_4_15_label" tabindex="0">
5266
+ <label class="md-nav__link " for="__nav_2_4_16" id="__nav_2_4_16_label" tabindex="0">
4505
5267
  <span class="md-nav__icon md-icon"></span>
4506
5268
  </label>
4507
5269
 
4508
5270
  </div>
4509
5271
 
4510
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_15_label" aria-expanded="false">
4511
- <label class="md-nav__title" for="__nav_2_4_15">
5272
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_16_label" aria-expanded="false">
5273
+ <label class="md-nav__title" for="__nav_2_4_16">
4512
5274
  <span class="md-nav__icon md-icon"></span>
4513
5275
  REST API
4514
5276
  </label>
@@ -4612,6 +5374,27 @@
4612
5374
 
4613
5375
 
4614
5376
 
5377
+ <li class="md-nav__item">
5378
+ <a href="../../user-guide/platform-functionality/savedview.html" class="md-nav__link">
5379
+
5380
+
5381
+ <span class="md-ellipsis">
5382
+ Saved Views
5383
+ </span>
5384
+
5385
+
5386
+ </a>
5387
+ </li>
5388
+
5389
+
5390
+
5391
+
5392
+
5393
+
5394
+
5395
+
5396
+
5397
+
4615
5398
  <li class="md-nav__item">
4616
5399
  <a href="../../user-guide/platform-functionality/secret.html" class="md-nav__link">
4617
5400
 
@@ -4707,10 +5490,10 @@
4707
5490
 
4708
5491
 
4709
5492
 
4710
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_21" >
5493
+ <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4_23" >
4711
5494
 
4712
5495
 
4713
- <label class="md-nav__link" for="__nav_2_4_21" id="__nav_2_4_21_label" tabindex="0">
5496
+ <label class="md-nav__link" for="__nav_2_4_23" id="__nav_2_4_23_label" tabindex="0">
4714
5497
 
4715
5498
 
4716
5499
  <span class="md-ellipsis">
@@ -4721,8 +5504,8 @@
4721
5504
  <span class="md-nav__icon md-icon"></span>
4722
5505
  </label>
4723
5506
 
4724
- <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_21_label" aria-expanded="false">
4725
- <label class="md-nav__title" for="__nav_2_4_21">
5507
+ <nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_4_23_label" aria-expanded="false">
5508
+ <label class="md-nav__title" for="__nav_2_4_23">
4726
5509
  <span class="md-nav__icon md-icon"></span>
4727
5510
  Users
4728
5511
  </label>
@@ -7277,6 +8060,27 @@
7277
8060
 
7278
8061
 
7279
8062
 
8063
+ <li class="md-nav__item">
8064
+ <a href="../../release-notes/version-2.3.html" class="md-nav__link">
8065
+
8066
+
8067
+ <span class="md-ellipsis">
8068
+ Version 2.3
8069
+ </span>
8070
+
8071
+
8072
+ </a>
8073
+ </li>
8074
+
8075
+
8076
+
8077
+
8078
+
8079
+
8080
+
8081
+
8082
+
8083
+
7280
8084
  <li class="md-nav__item">
7281
8085
  <a href="../../release-notes/version-2.2.html" class="md-nav__link">
7282
8086
 
@@ -8568,6 +9372,21 @@
8568
9372
  </code></pre></div>
8569
9373
  <p>Similarly, only the <code>jobs</code> module is loaded from Git repositories. If you're using submodules, you need to ensure that your jobs are either registered in the repository's <code>jobs/__init__.py</code> or that this file imports your submodules where the jobs are registered.</p>
8570
9374
  <p>If not using submodules, you should register your job in the file where your job is defined.</p>
9375
+ <p>Examples of the different directory structures when registering jobs in Git repositories: </p>
9376
+ <div class="admonition note">
9377
+ <p class="admonition-title">Note</p>
9378
+ <p>Take note of the <code>__init__.py</code> at the root of the repository. This is required to register jobs in a Git repository.</p>
9379
+ </div>
9380
+ <div class="highlight"><span class="filename">jobs.py</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>.
9381
+ <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>├── __init__.py
9382
+ <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>└── jobs.py
9383
+ </code></pre></div>
9384
+ <div class="highlight"><span class="filename">submodule</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>.
9385
+ <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>├── __init__.py
9386
+ <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a>└── jobs
9387
+ <a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a> ├── __init__.py
9388
+ <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> └── my_job_module.py
9389
+ </code></pre></div>
8571
9390
  <h4 id="registering-jobs-in-an-app">Registering Jobs in an App<a class="headerlink" href="#registering-jobs-in-an-app" title="Permanent link">&para;</a></h4>
8572
9391
  <p>Apps should register jobs in the module defined in their <a href="../apps/api/nautobot-app-config.html#nautobotappconfig-code-location-attributes"><code>NautobotAppConfig.jobs</code></a> property. This defaults to the <code>jobs</code> module of the App.</p>
8573
9392
  <h3 id="reserved-attribute-names">Reserved Attribute Names<a class="headerlink" href="#reserved-attribute-names" title="Permanent link">&para;</a></h3>
@@ -8765,15 +9584,15 @@
8765
9584
  <h4 id="description"><code>description</code><a class="headerlink" href="#description" title="Permanent link">&para;</a></h4>
8766
9585
  <p>An optional human-friendly description of what this job does.
8767
9586
  This can accept either plain text, Markdown-formatted text, or <a href="../../user-guide/platform-functionality/template-filters.html#render_markdown">a limited subset of HTML</a>. It can also be multiple lines:</p>
8768
- <div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="k">class</span> <span class="nc">ExampleJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8769
- <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
8770
- <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
8771
- <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="s2"> This job does a number of interesting things.</span>
8772
- <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a>
8773
- <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="s2"> 1. It hacks the Gibson</span>
8774
- <a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a><span class="s2"> 2. It immanentizes the eschaton</span>
8775
- <a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a><span class="s2"> 3. It&#39;s a floor wax *and* a dessert topping</span>
8776
- <a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a><span class="s2"> &quot;&quot;&quot;</span>
9587
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="k">class</span> <span class="nc">ExampleJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9588
+ <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9589
+ <a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
9590
+ <a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="s2"> This job does a number of interesting things.</span>
9591
+ <a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a>
9592
+ <a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a><span class="s2"> 1. It hacks the Gibson</span>
9593
+ <a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a><span class="s2"> 2. It immanentizes the eschaton</span>
9594
+ <a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="s2"> 3. It&#39;s a floor wax *and* a dessert topping</span>
9595
+ <a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a><span class="s2"> &quot;&quot;&quot;</span>
8777
9596
  </code></pre></div>
8778
9597
  <p>If you code a multi-line description, the first line only will be used in the description column of the jobs list, while the full description will be rendered in the job detail view, submission, approval, and results pages.</p>
8779
9598
  <h4 id="approval_required"><code>approval_required</code><a class="headerlink" href="#approval_required" title="Permanent link">&para;</a></h4>
@@ -8786,9 +9605,9 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
8786
9605
  </details>
8787
9606
  <p>Default: <code>False</code></p>
8788
9607
  <p>The checkbox to enable dryrun when executing a job is unchecked by default in the Nautobot UI. You can set <code>dryrun_default</code> to <code>True</code> under the <code>Meta</code> class if you want this option to instead be checked by default.</p>
8789
- <div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8790
- <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
8791
- <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a> <span class="n">dryrun_default</span> <span class="o">=</span> <span class="kc">True</span>
9608
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9609
+ <a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9610
+ <a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> <span class="n">dryrun_default</span> <span class="o">=</span> <span class="kc">True</span>
8792
9611
  </code></pre></div>
8793
9612
  <h4 id="field_order"><code>field_order</code><a class="headerlink" href="#field_order" title="Permanent link">&para;</a></h4>
8794
9613
  <p>Default: <code>[]</code></p>
@@ -8832,22 +9651,22 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
8832
9651
  </details>
8833
9652
  <p>An int or float value, in seconds, which can be used to override the default <a href="../../user-guide/administration/configuration/optional-settings.html#celery_task_soft_time_limit">soft time limit</a> for a job task to complete.</p>
8834
9653
  <p>The <code>celery.exceptions.SoftTimeLimitExceeded</code> exception will be raised when this soft time limit is exceeded. The job task can catch this to clean up before the <a href="../../user-guide/administration/configuration/optional-settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) is reached:</p>
8835
- <div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="kn">from</span> <span class="nn">celery.exceptions</span> <span class="kn">import</span> <span class="n">SoftTimeLimitExceeded</span>
8836
- <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
8837
- <a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a>
8838
- <a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="k">class</span> <span class="nc">ExampleJobWithSoftTimeLimit</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8839
- <a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
8840
- <a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Soft Time Limit&quot;</span>
8841
- <a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Set a soft time limit of 10 seconds`&quot;</span>
8842
- <a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="n">soft_time_limit</span> <span class="o">=</span> <span class="mi">10</span>
8843
- <a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a>
8844
- <a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
8845
- <a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="k">try</span><span class="p">:</span>
8846
- <a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="c1"># code which might take longer than 10 seconds to run</span>
8847
- <a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="n">job_code</span><span class="p">()</span>
8848
- <a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="k">except</span> <span class="n">SoftTimeLimitExceeded</span><span class="p">:</span>
8849
- <a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="c1"># any clean up code</span>
8850
- <a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> <span class="n">cleanup_in_a_hurry</span><span class="p">()</span>
9654
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="kn">from</span> <span class="nn">celery.exceptions</span> <span class="kn">import</span> <span class="n">SoftTimeLimitExceeded</span>
9655
+ <a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9656
+ <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>
9657
+ <a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="k">class</span> <span class="nc">ExampleJobWithSoftTimeLimit</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9658
+ <a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9659
+ <a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Soft Time Limit&quot;</span>
9660
+ <a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Set a soft time limit of 10 seconds`&quot;</span>
9661
+ <a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a> <span class="n">soft_time_limit</span> <span class="o">=</span> <span class="mi">10</span>
9662
+ <a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a>
9663
+ <a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
9664
+ <a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> <span class="k">try</span><span class="p">:</span>
9665
+ <a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> <span class="c1"># code which might take longer than 10 seconds to run</span>
9666
+ <a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a> <span class="n">job_code</span><span class="p">()</span>
9667
+ <a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a> <span class="k">except</span> <span class="n">SoftTimeLimitExceeded</span><span class="p">:</span>
9668
+ <a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a> <span class="c1"># any clean up code</span>
9669
+ <a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a> <span class="n">cleanup_in_a_hurry</span><span class="p">()</span>
8851
9670
  </code></pre></div>
8852
9671
  <h4 id="task_queues"><code>task_queues</code><a class="headerlink" href="#task_queues" title="Permanent link">&para;</a></h4>
8853
9672
  <details class="version-added">
@@ -8865,20 +9684,20 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
8865
9684
  </details>
8866
9685
  <p>A path relative to the job source code containing a Django template which provides additional code to customize the Job's submission form. This template should extend the existing job template, <code>extras/job.html</code>, otherwise the base form and functionality may not be available.</p>
8867
9686
  <p>A template can provide additional JavaScript, CSS, or even display HTML. A good starting template would be:</p>
8868
- <div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>{% extends &#39;extras/job.html&#39; %}
8869
- <a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>
8870
- <a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a>{% block extra_styles %}
8871
- <a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a> {{ block.super }}
8872
- <a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a> <span class="cm">&lt;!-- Add additional CSS here. --&gt;</span>
8873
- <a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a>{% endblock %}
8874
- <a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a>{% block content %}
8875
- <a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a> {{ block.super }}
8876
- <a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a> <span class="cm">&lt;!-- Add additional HTML here. --&gt;</span>
8877
- <a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a>{% endblock content %}
8878
- <a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a>{% block javascript %}
8879
- <a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a> {{ block.super }}
8880
- <a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a> <span class="cm">&lt;!-- Add additional JavaScript here. --&gt;</span>
8881
- <a id="__codelineno-6-14" name="__codelineno-6-14" href="#__codelineno-6-14"></a>{% endblock javascript %}
9687
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>{% extends &#39;extras/job.html&#39; %}
9688
+ <a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>
9689
+ <a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a>{% block extra_styles %}
9690
+ <a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a> {{ block.super }}
9691
+ <a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="cm">&lt;!-- Add additional CSS here. --&gt;</span>
9692
+ <a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a>{% endblock %}
9693
+ <a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a>{% block content %}
9694
+ <a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a> {{ block.super }}
9695
+ <a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a> <span class="cm">&lt;!-- Add additional HTML here. --&gt;</span>
9696
+ <a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a>{% endblock content %}
9697
+ <a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a>{% block javascript %}
9698
+ <a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a> {{ block.super }}
9699
+ <a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a> <span class="cm">&lt;!-- Add additional JavaScript here. --&gt;</span>
9700
+ <a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a>{% endblock javascript %}
8882
9701
  </code></pre></div>
8883
9702
  <details class="version-added">
8884
9703
  <summary>Added in version 2.2.0</summary>
@@ -8892,18 +9711,18 @@ This can accept either plain text, Markdown-formatted text, or <a href="../../us
8892
9711
  <p>An int or float value, in seconds, which can be used to override the
8893
9712
  default <a href="../../user-guide/administration/configuration/optional-settings.html#celery_task_time_limit">hard time limit</a> (10 minutes by default) for a job task to complete.</p>
8894
9713
  <p>Unlike the <code>soft_time_limit</code> above, no exceptions are raised when a <code>time_limit</code> is exceeded. The task will just terminate silently:</p>
8895
- <div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
8896
- <a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>
8897
- <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="k">class</span> <span class="nc">ExampleJobWithHardTimeLimit</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8898
- <a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
8899
- <a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Hard Time Limit&quot;</span>
8900
- <a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Set a hard time limit of 10 seconds`&quot;</span>
8901
- <a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="n">time_limit</span> <span class="o">=</span> <span class="mi">10</span>
8902
- <a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a>
8903
- <a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-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>
8904
- <a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a> <span class="c1"># code which might take longer than 10 seconds to run</span>
8905
- <a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> <span class="c1"># this code will fail silently if the time_limit is exceeded</span>
8906
- <a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> <span class="n">job_code</span><span class="p">()</span>
9714
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9715
+ <a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>
9716
+ <a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="k">class</span> <span class="nc">ExampleJobWithHardTimeLimit</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9717
+ <a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9718
+ <a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Hard Time Limit&quot;</span>
9719
+ <a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Set a hard time limit of 10 seconds`&quot;</span>
9720
+ <a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a> <span class="n">time_limit</span> <span class="o">=</span> <span class="mi">10</span>
9721
+ <a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a>
9722
+ <a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-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>
9723
+ <a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a> <span class="c1"># code which might take longer than 10 seconds to run</span>
9724
+ <a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a> <span class="c1"># this code will fail silently if the time_limit is exceeded</span>
9725
+ <a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a> <span class="n">job_code</span><span class="p">()</span>
8907
9726
  </code></pre></div>
8908
9727
  <div class="admonition note">
8909
9728
  <p class="admonition-title">Note</p>
@@ -8911,15 +9730,15 @@ default <a href="../../user-guide/administration/configuration/optional-settings
8911
9730
  </div>
8912
9731
  <h3 id="variables">Variables<a class="headerlink" href="#variables" title="Permanent link">&para;</a></h3>
8913
9732
  <p>Variables allow your job to accept user input via the Nautobot UI, but they are optional; if your job does not require any user input, there is no need to define any variables. Conversely, if you are making use of user input in your job, you <em>must</em> also implement the <code>run()</code> method, as it is the only entry point to your job that has visibility into the variable values provided by the user.</p>
8914
- <div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
8915
- <a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>
8916
- <a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8917
- <a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-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>
8918
- <a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="n">var2</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
8919
- <a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a> <span class="n">var3</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
8920
- <a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a>
8921
- <a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
8922
- <a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a> <span class="o">...</span>
9733
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
9734
+ <a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>
9735
+ <a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9736
+ <a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-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>
9737
+ <a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a> <span class="n">var2</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9738
+ <a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a> <span class="n">var3</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9739
+ <a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a>
9740
+ <a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
9741
+ <a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a> <span class="o">...</span>
8923
9742
  </code></pre></div>
8924
9743
  <p>The remainder of this section documents the various supported variable types and how to make use of them.</p>
8925
9744
  <h4 id="default-variable-options">Default Variable Options<a class="headerlink" href="#default-variable-options" title="Permanent link">&para;</a></h4>
@@ -8946,12 +9765,12 @@ default <a href="../../user-guide/administration/configuration/optional-settings
8946
9765
  <summary>Added in version 2.1.0</summary>
8947
9766
  </details>
8948
9767
  <p>Accepts JSON-formatted data of any length. Renders as a multi-line text input field. The variable passed to <code>run()</code> method on the job has been serialized to the appropriate Python objects.</p>
8949
- <div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="k">class</span> <span class="nc">ExampleJSONVarJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
8950
- <a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a> <span class="n">var1</span> <span class="o">=</span> <span class="n">JSONVar</span><span class="p">()</span>
8951
- <a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>
8952
- <a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-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> <span class="n">var1</span><span class="p">):</span>
8953
- <a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a> <span class="c1"># var1 form data equals &#39;{&quot;key1&quot;: &quot;value1&quot;}&#39;</span>
8954
- <a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;The value of key1 is: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">var1</span><span class="p">[</span><span class="s2">&quot;key1&quot;</span><span class="p">])</span>
9768
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="k">class</span> <span class="nc">ExampleJSONVarJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9769
+ <a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a> <span class="n">var1</span> <span class="o">=</span> <span class="n">JSONVar</span><span class="p">()</span>
9770
+ <a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
9771
+ <a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-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> <span class="n">var1</span><span class="p">):</span>
9772
+ <a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a> <span class="c1"># var1 form data equals &#39;{&quot;key1&quot;: &quot;value1&quot;}&#39;</span>
9773
+ <a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;The value of key1 is: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">var1</span><span class="p">[</span><span class="s2">&quot;key1&quot;</span><span class="p">])</span>
8955
9774
  </code></pre></div>
8956
9775
  <p>In the above example <code>{"key1": "value1"}</code> is provided to the job form, on submission first the field is validated to be JSON-formatted data then is serialized and passed to the <code>run()</code> method as a dictionary without any need for the job developer to post-process the variable into a Python dictionary.</p>
8957
9776
  <h4 id="integervar"><code>IntegerVar</code><a class="headerlink" href="#integervar" title="Permanent link">&para;</a></h4>
@@ -8969,14 +9788,14 @@ default <a href="../../user-guide/administration/configuration/optional-settings
8969
9788
  <ul>
8970
9789
  <li><code>choices</code> - A list of <code>(value, label)</code> tuples representing the available choices. For example:</li>
8971
9790
  </ul>
8972
- <div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="n">CHOICES</span> <span class="o">=</span> <span class="p">(</span>
8973
- <a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a> <span class="p">(</span><span class="s1">&#39;n&#39;</span><span class="p">,</span> <span class="s1">&#39;North&#39;</span><span class="p">),</span>
8974
- <a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a> <span class="p">(</span><span class="s1">&#39;s&#39;</span><span class="p">,</span> <span class="s1">&#39;South&#39;</span><span class="p">),</span>
8975
- <a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a> <span class="p">(</span><span class="s1">&#39;e&#39;</span><span class="p">,</span> <span class="s1">&#39;East&#39;</span><span class="p">),</span>
8976
- <a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a> <span class="p">(</span><span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="s1">&#39;West&#39;</span><span class="p">)</span>
8977
- <a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="p">)</span>
8978
- <a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a>
8979
- <a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a><span class="n">direction</span> <span class="o">=</span> <span class="n">ChoiceVar</span><span class="p">(</span><span class="n">choices</span><span class="o">=</span><span class="n">CHOICES</span><span class="p">)</span>
9791
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="n">CHOICES</span> <span class="o">=</span> <span class="p">(</span>
9792
+ <a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a> <span class="p">(</span><span class="s1">&#39;n&#39;</span><span class="p">,</span> <span class="s1">&#39;North&#39;</span><span class="p">),</span>
9793
+ <a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> <span class="p">(</span><span class="s1">&#39;s&#39;</span><span class="p">,</span> <span class="s1">&#39;South&#39;</span><span class="p">),</span>
9794
+ <a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a> <span class="p">(</span><span class="s1">&#39;e&#39;</span><span class="p">,</span> <span class="s1">&#39;East&#39;</span><span class="p">),</span>
9795
+ <a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a> <span class="p">(</span><span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="s1">&#39;West&#39;</span><span class="p">)</span>
9796
+ <a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="p">)</span>
9797
+ <a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a>
9798
+ <a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a><span class="n">direction</span> <span class="o">=</span> <span class="n">ChoiceVar</span><span class="p">(</span><span class="n">choices</span><span class="o">=</span><span class="n">CHOICES</span><span class="p">)</span>
8980
9799
  </code></pre></div>
8981
9800
  <p>In the example above, selecting the choice labeled "North" will submit the value <code>n</code>.</p>
8982
9801
  <h4 id="multichoicevar"><code>MultiChoiceVar</code><a class="headerlink" href="#multichoicevar" title="Permanent link">&para;</a></h4>
@@ -8990,52 +9809,52 @@ default <a href="../../user-guide/administration/configuration/optional-settings
8990
9809
  <li><code>null_option</code> - A label representing a "null" or empty choice (optional)</li>
8991
9810
  </ul>
8992
9811
  <p>The <code>display_field</code> argument is useful in cases where using the <code>display</code> API field is not desired for referencing the object. For example, when displaying a list of IP Addresses, you might want to use the <code>dns_name</code> field:</p>
8993
- <div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
8994
- <a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">IPAddress</span><span class="p">,</span>
8995
- <a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;dns_name&quot;</span><span class="p">,</span>
8996
- <a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="p">)</span>
9812
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9813
+ <a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">IPAddress</span><span class="p">,</span>
9814
+ <a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;dns_name&quot;</span><span class="p">,</span>
9815
+ <a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="p">)</span>
8997
9816
  </code></pre></div>
8998
9817
  <p>Additionally, the <code>.</code> notation can be used to reference nested fields:</p>
8999
- <div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9000
- <a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">VLAN</span><span class="p">,</span>
9001
- <a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;vlan_group.name&quot;</span><span class="p">,</span>
9002
- <a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9003
- <a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a> <span class="s2">&quot;depth&quot;</span><span class="p">:</span> <span class="mi">1</span>
9004
- <a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a> <span class="p">},</span>
9005
- <a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a><span class="p">)</span>
9818
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9819
+ <a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">VLAN</span><span class="p">,</span>
9820
+ <a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;vlan_group.name&quot;</span><span class="p">,</span>
9821
+ <a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9822
+ <a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a> <span class="s2">&quot;depth&quot;</span><span class="p">:</span> <span class="mi">1</span>
9823
+ <a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a> <span class="p">},</span>
9824
+ <a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="p">)</span>
9006
9825
  </code></pre></div>
9007
9826
  <p>In the example above, <a href="../../user-guide/platform-functionality/rest-api/overview.html#depth-query-parameter"><code>"depth": 1</code></a> was needed to influence REST API to include details of the associated records.
9008
9827
  Another example of using the nested reference would be to access <a href="../../user-guide/platform-functionality/computedfield.html">computed fields</a> of the model:</p>
9009
- <div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9010
- <a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Interface</span><span class="p">,</span>
9011
- <a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;computed_fields.mycustomfield&quot;</span><span class="p">,</span>
9012
- <a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9013
- <a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a> <span class="s2">&quot;include&quot;</span><span class="p">:</span> <span class="s2">&quot;computed_fields&quot;</span>
9014
- <a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a> <span class="p">},</span>
9015
- <a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="p">)</span>
9828
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="n">device_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9829
+ <a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Interface</span><span class="p">,</span>
9830
+ <a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a> <span class="n">display_field</span><span class="o">=</span><span class="s2">&quot;computed_fields.mycustomfield&quot;</span><span class="p">,</span>
9831
+ <a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9832
+ <a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a> <span class="s2">&quot;include&quot;</span><span class="p">:</span> <span class="s2">&quot;computed_fields&quot;</span>
9833
+ <a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a> <span class="p">},</span>
9834
+ <a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="p">)</span>
9016
9835
  </code></pre></div>
9017
9836
  <p>To limit the selections available within the list, additional query parameters can be passed as the <code>query_params</code> dictionary. For example, to show only devices with an "active" status:</p>
9018
- <div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="n">device</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9019
- <a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Device</span><span class="p">,</span>
9020
- <a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9021
- <a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a> <span class="s1">&#39;status&#39;</span><span class="p">:</span> <span class="s1">&#39;active&#39;</span>
9022
- <a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a> <span class="p">}</span>
9023
- <a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="p">)</span>
9837
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="n">device</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9838
+ <a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">Device</span><span class="p">,</span>
9839
+ <a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9840
+ <a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a> <span class="s1">&#39;status&#39;</span><span class="p">:</span> <span class="s1">&#39;active&#39;</span>
9841
+ <a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a> <span class="p">}</span>
9842
+ <a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="p">)</span>
9024
9843
  </code></pre></div>
9025
9844
  <p>Multiple values can be specified by assigning a list to the dictionary key. It is also possible to reference the value of other fields in the form by prepending a dollar sign (<code>$</code>) to the variable's name. The keys you can use in this dictionary are the same ones that are available in the REST API - as an example it is also possible to filter the <code>Location</code> <code>ObjectVar</code> for its <code>location_type</code> and <code>tenant_group</code>.</p>
9026
- <div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="n">location_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9027
- <a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">LocationType</span>
9028
- <a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="p">)</span>
9029
- <a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="n">tenant_group</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9030
- <a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a> <span class="n">model</span><span class="o">=</span><span class="n">TenantGroup</span>
9031
- <a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="p">)</span>
9032
- <a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="n">location</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9033
- <a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a> <span class="n">model</span><span class="o">=</span><span class="n">Location</span><span class="p">,</span>
9034
- <a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9035
- <a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a> <span class="s2">&quot;location_type&quot;</span><span class="p">:</span> <span class="s2">&quot;$location_type&quot;</span><span class="p">,</span>
9036
- <a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a> <span class="s2">&quot;tenant_group&quot;</span><span class="p">:</span> <span class="s2">&quot;$tenant_group&quot;</span>
9037
- <a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a> <span class="p">}</span>
9038
- <a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="p">)</span>
9845
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="n">location_type</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9846
+ <a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a> <span class="n">model</span><span class="o">=</span><span class="n">LocationType</span>
9847
+ <a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="p">)</span>
9848
+ <a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="n">tenant_group</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9849
+ <a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a> <span class="n">model</span><span class="o">=</span><span class="n">TenantGroup</span>
9850
+ <a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a><span class="p">)</span>
9851
+ <a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a><span class="n">location</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9852
+ <a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a> <span class="n">model</span><span class="o">=</span><span class="n">Location</span><span class="p">,</span>
9853
+ <a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a> <span class="n">query_params</span><span class="o">=</span><span class="p">{</span>
9854
+ <a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a> <span class="s2">&quot;location_type&quot;</span><span class="p">:</span> <span class="s2">&quot;$location_type&quot;</span><span class="p">,</span>
9855
+ <a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a> <span class="s2">&quot;tenant_group&quot;</span><span class="p">:</span> <span class="s2">&quot;$tenant_group&quot;</span>
9856
+ <a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a> <span class="p">}</span>
9857
+ <a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a><span class="p">)</span>
9039
9858
  </code></pre></div>
9040
9859
  <h4 id="multiobjectvar"><code>MultiObjectVar</code><a class="headerlink" href="#multiobjectvar" title="Permanent link">&para;</a></h4>
9041
9860
  <p>Similar to <code>ObjectVar</code>, but allows for the selection of multiple objects.</p>
@@ -9063,15 +9882,15 @@ Another example of using the nested reference would be to access <a href="../../
9063
9882
  <p>The return value from <code>before_start()</code> is ignored, but if it raises any exception, the Job execution will be marked as a failure and <code>run()</code> will not be called.</p>
9064
9883
  <h4 id="the-run-method">The <code>run()</code> Method<a class="headerlink" href="#the-run-method" title="Permanent link">&para;</a></h4>
9065
9884
  <p>The <code>run()</code> method is the primary worker of any Job, and must be implemented. After the <code>self</code> argument, it should accept keyword arguments for any variables defined on the job:</p>
9066
- <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.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>
9067
- <a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>
9068
- <a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9069
- <a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-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>
9070
- <a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a> <span class="n">var2</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9071
- <a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a> <span class="n">var3</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9072
- <a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a>
9073
- <a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
9074
- <a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a> <span class="o">...</span>
9885
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
9886
+ <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>
9887
+ <a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9888
+ <a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-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>
9889
+ <a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a> <span class="n">var2</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9890
+ <a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a> <span class="n">var3</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
9891
+ <a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a>
9892
+ <a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
9893
+ <a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a> <span class="o">...</span>
9075
9894
  </code></pre></div>
9076
9895
  <p>Again, defining user variables is totally optional; you may create a job with a <code>run()</code> method with only the <code>self</code> argument if no user input is needed.</p>
9077
9896
  <div class="admonition warning">
@@ -9104,21 +9923,21 @@ Another example of using the nested reference would be to access <a href="../../
9104
9923
  <p>If a <code>grouping</code> is not provided it will default to the function name that logged the message. The <code>object</code> will default to <code>None</code>.</p>
9105
9924
  <div class="admonition example">
9106
9925
  <p class="admonition-title">Example</p>
9107
- <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.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9108
- <a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a>
9109
- <a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-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>
9110
- <a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-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>
9111
- <a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;This job is running!&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;grouping&quot;</span><span class="p">:</span> <span class="s2">&quot;myjobisrunning&quot;</span><span class="p">,</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">job_result</span><span class="p">})</span>
9926
+ <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>
9927
+ <a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>
9928
+ <a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-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>
9929
+ <a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-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>
9930
+ <a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;This job is running!&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;grouping&quot;</span><span class="p">:</span> <span class="s2">&quot;myjobisrunning&quot;</span><span class="p">,</span> <span class="s2">&quot;object&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">job_result</span><span class="p">})</span>
9112
9931
  </code></pre></div>
9113
9932
  </div>
9114
9933
  <p>To skip writing a log entry to the database, set the <code>skip_db_logging</code> key in the "extra" kwarg to <code>True</code> when calling the log function. The output will still be written to the console.</p>
9115
9934
  <div class="admonition example">
9116
9935
  <p class="admonition-title">Example</p>
9117
- <div class="highlight"><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9118
- <a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a>
9119
- <a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-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>
9120
- <a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-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>
9121
- <a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;This job is running!&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;skip_db_logging&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">})</span>
9936
+ <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>
9937
+ <a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>
9938
+ <a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-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>
9939
+ <a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-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>
9940
+ <a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;This job is running!&quot;</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;skip_db_logging&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">})</span>
9122
9941
  </code></pre></div>
9123
9942
  </div>
9124
9943
  <p>Markdown rendering is supported for log messages, as well as <a href="../../user-guide/platform-functionality/template-filters.html#render_markdown">a limited subset of HTML</a>.</p>
@@ -9139,27 +9958,27 @@ Another example of using the nested reference would be to access <a href="../../
9139
9958
  <summary>Added in version 2.1.0</summary>
9140
9959
  </details>
9141
9960
  <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>
9142
- <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.extras.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9143
- <a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>
9144
- <a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-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>
9145
- <a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-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>
9146
- <a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-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>
9147
- <a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-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>
9961
+ <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.extras.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
9962
+ <a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a>
9963
+ <a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-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>
9964
+ <a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-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>
9965
+ <a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-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>
9966
+ <a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-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>
9148
9967
  </code></pre></div>
9149
- <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>
9968
+ <p>The above Job when run will create two files, "greeting.txt" and "farewell.txt", that will be made available for download from the JobResult detail view's "Advanced" tab and via the REST API. These files will persist indefinitely, but can automatically be deleted if the JobResult itself is deleted; they can also be deleted manually by an administrator via the "File Proxies" link in the Admin UI.</p>
9150
9969
  <p>The maximum size of any single created file (or in other words, the maximum number of bytes that can be passed to <code>self.create_file()</code>) is controlled by the <a href="../../user-guide/administration/configuration/optional-settings.html#job_create_file_max_size"><code>JOB_CREATE_FILE_MAX_SIZE</code></a> system setting. A <code>ValueError</code> exception will be raised if <code>create_file()</code> is called with an overly large <code>content</code> value.</p>
9151
9970
  <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>
9152
9971
  <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>
9153
9972
  <p>As an example, the following job will fail if the user does not put the word "Taco" in <code>var1</code>:</p>
9154
- <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><span class="p">,</span> <span class="n">StringVar</span>
9155
- <a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>
9156
- <a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-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>
9157
- <a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-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>
9158
- <a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>
9159
- <a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-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>
9160
- <a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-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>
9161
- <a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-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>
9162
- <a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-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>
9973
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span>
9974
+ <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>
9975
+ <a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="k">class</span> <span class="nc">MyJob</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
9976
+ <a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-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>
9977
+ <a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a>
9978
+ <a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-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>
9979
+ <a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-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>
9980
+ <a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-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>
9981
+ <a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-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>
9163
9982
  </code></pre></div>
9164
9983
  <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>
9165
9984
  <details class="version-changed">
@@ -9167,9 +9986,9 @@ Another example of using the nested reference would be to access <a href="../../
9167
9986
  <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>
9168
9987
  </details>
9169
9988
  <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>
9170
- <div class="highlight"><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-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>
9171
- <a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-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>
9172
- <a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-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>
9989
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="n">username</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">username</span>
9990
+ <a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="n">job_result_id</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">job_result</span><span class="o">.</span><span class="n">id</span>
9991
+ <a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Job </span><span class="si">%s</span><span class="s2"> initiated by user </span><span class="si">%s</span><span class="s2"> is running.&quot;</span><span class="p">,</span> <span class="n">job_result_id</span><span class="p">,</span> <span class="n">username</span><span class="p">)</span>
9173
9992
  </code></pre></div>
9174
9993
  <h3 id="reading-data-from-files">Reading Data from Files<a class="headerlink" href="#reading-data-from-files" title="Permanent link">&para;</a></h3>
9175
9994
  <p>The <code>Job</code> class provides two convenience methods for reading data from files:</p>
@@ -9190,21 +10009,21 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9190
10009
  <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>
9191
10010
  <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>
9192
10011
  <p>A simple example of a Job test case might look like the following:</p>
9193
- <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.testing</span> <span class="kn">import</span> <span class="n">run_job_for_testing</span><span class="p">,</span> <span class="n">TransactionTestCase</span>
9194
- <a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-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>
9195
- <a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>
9196
- <a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a>
9197
- <a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-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>
9198
- <a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-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>
9199
- <a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a> <span class="c1"># Testing of Job &quot;MyJob&quot; in file &quot;my_job_file.py&quot; in $JOBS_ROOT</span>
9200
- <a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-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>
9201
- <a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a> <span class="c1"># or, job = Job.objects.get_for_class_path(&quot;local/my_job_file/MyJob&quot;)</span>
9202
- <a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-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>
9203
- <a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a>
9204
- <a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a> <span class="c1"># Inspect the logs created by running the job</span>
9205
- <a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-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>
9206
- <a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-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>
9207
- <a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-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>
10012
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.testing</span> <span class="kn">import</span> <span class="n">run_job_for_testing</span><span class="p">,</span> <span class="n">TransactionTestCase</span>
10013
+ <a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">JobLogEntry</span>
10014
+ <a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>
10015
+ <a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>
10016
+ <a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-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>
10017
+ <a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-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>
10018
+ <a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a> <span class="c1"># Testing of Job &quot;MyJob&quot; in file &quot;my_job_file.py&quot; in $JOBS_ROOT</span>
10019
+ <a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-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>
10020
+ <a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a> <span class="c1"># or, job = Job.objects.get_for_class_path(&quot;local/my_job_file/MyJob&quot;)</span>
10021
+ <a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-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>
10022
+ <a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a>
10023
+ <a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-12"></a> <span class="c1"># Inspect the logs created by running the job</span>
10024
+ <a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-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>
10025
+ <a id="__codelineno-24-14" name="__codelineno-24-14" href="#__codelineno-24-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>
10026
+ <a id="__codelineno-24-15" name="__codelineno-24-15" href="#__codelineno-24-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>
9208
10027
  </code></pre></div>
9209
10028
  <div class="admonition tip">
9210
10029
  <p class="admonition-title">Tip</p>
@@ -9222,10 +10041,10 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9222
10041
  </div>
9223
10042
  <h3 id="reading-profiling-reports">Reading profiling reports<a class="headerlink" href="#reading-profiling-reports" title="Permanent link">&para;</a></h3>
9224
10043
  <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>
9225
- <div class="highlight"><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="kn">import</span> <span class="nn">pstats</span>
9226
- <a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="n">job_result_uuid</span> <span class="o">=</span> <span class="s2">&quot;66b70231-002f-412b-8cc4-1cc9609c2c9b&quot;</span>
9227
- <a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="n">stats</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;/tmp/nautobot-jobresult-</span><span class="si">{</span><span class="n">job_result_uuid</span><span class="si">}</span><span class="s2">.pstats&quot;</span><span class="p">)</span>
9228
- <a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-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>
10044
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="kn">import</span> <span class="nn">pstats</span>
10045
+ <a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="n">job_result_uuid</span> <span class="o">=</span> <span class="s2">&quot;66b70231-002f-412b-8cc4-1cc9609c2c9b&quot;</span>
10046
+ <a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="n">stats</span> <span class="o">=</span> <span class="n">pstats</span><span class="o">.</span><span class="n">Stats</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;/tmp/nautobot-jobresult-</span><span class="si">{</span><span class="n">job_result_uuid</span><span class="si">}</span><span class="s2">.pstats&quot;</span><span class="p">)</span>
10047
+ <a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="n">stats</span><span class="o">.</span><span class="n">sort_stats</span><span class="p">(</span><span class="n">pstats</span><span class="o">.</span><span class="n">SortKey</span><span class="o">.</span><span class="n">CUMULATIVE</span><span class="p">)</span><span class="o">.</span><span class="n">print_stats</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
9229
10048
  </code></pre></div>
9230
10049
  <p>This will print the 10 functions that the job execution spent the most time in - adapt this to your needs!</p>
9231
10050
  <h2 id="example-jobs">Example Jobs<a class="headerlink" href="#example-jobs" title="Permanent link">&para;</a></h2>
@@ -9237,117 +10056,116 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9237
10056
  <li>The number of access switches to create</li>
9238
10057
  </ul>
9239
10058
  <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>
9240
- <div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span>
9241
- <a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>
9242
- <a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span><span class="p">,</span> <span class="n">register_jobs</span>
9243
- <a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-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>
9244
- <a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-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>
9245
- <a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a>
9246
- <a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a>
9247
- <a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-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>
9248
- <a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9249
- <a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-10"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;New Branch&quot;</span>
9250
- <a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Provision a new branch location&quot;</span>
9251
- <a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-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>
9252
- <a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-13"></a>
9253
- <a id="__codelineno-24-14" name="__codelineno-24-14" href="#__codelineno-24-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>
9254
- <a id="__codelineno-24-15" name="__codelineno-24-15" href="#__codelineno-24-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>
9255
- <a id="__codelineno-24-16" name="__codelineno-24-16" href="#__codelineno-24-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>
9256
- <a id="__codelineno-24-17" name="__codelineno-24-17" href="#__codelineno-24-17"></a> <span class="n">switch_model</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
9257
- <a id="__codelineno-24-18" name="__codelineno-24-18" href="#__codelineno-24-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>
9258
- <a id="__codelineno-24-19" name="__codelineno-24-19" href="#__codelineno-24-19"></a> <span class="p">)</span>
9259
- <a id="__codelineno-24-20" name="__codelineno-24-20" href="#__codelineno-24-20"></a>
9260
- <a id="__codelineno-24-21" name="__codelineno-24-21" href="#__codelineno-24-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>
9261
- <a id="__codelineno-24-22" name="__codelineno-24-22" href="#__codelineno-24-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>
9262
- <a id="__codelineno-24-23" name="__codelineno-24-23" href="#__codelineno-24-23"></a>
9263
- <a id="__codelineno-24-24" name="__codelineno-24-24" href="#__codelineno-24-24"></a> <span class="c1"># Create the new location</span>
9264
- <a id="__codelineno-24-25" name="__codelineno-24-25" href="#__codelineno-24-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>
9265
- <a id="__codelineno-24-26" name="__codelineno-24-26" href="#__codelineno-24-26"></a> <span class="n">location</span> <span class="o">=</span> <span class="n">Location</span><span class="p">(</span>
9266
- <a id="__codelineno-24-27" name="__codelineno-24-27" href="#__codelineno-24-27"></a> <span class="n">name</span><span class="o">=</span><span class="n">location_name</span><span class="p">,</span>
9267
- <a id="__codelineno-24-28" name="__codelineno-24-28" href="#__codelineno-24-28"></a> <span class="n">location_type</span><span class="o">=</span><span class="n">root_type</span><span class="p">,</span>
9268
- <a id="__codelineno-24-29" name="__codelineno-24-29" href="#__codelineno-24-29"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
9269
- <a id="__codelineno-24-30" name="__codelineno-24-30" href="#__codelineno-24-30"></a> <span class="p">)</span>
9270
- <a id="__codelineno-24-31" name="__codelineno-24-31" href="#__codelineno-24-31"></a> <span class="n">location</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
9271
- <a id="__codelineno-24-32" name="__codelineno-24-32" href="#__codelineno-24-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>
9272
- <a id="__codelineno-24-33" name="__codelineno-24-33" href="#__codelineno-24-33"></a>
9273
- <a id="__codelineno-24-34" name="__codelineno-24-34" href="#__codelineno-24-34"></a> <span class="c1"># Create access switches</span>
9274
- <a id="__codelineno-24-35" name="__codelineno-24-35" href="#__codelineno-24-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>
9275
- <a id="__codelineno-24-36" name="__codelineno-24-36" href="#__codelineno-24-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>
9276
- <a id="__codelineno-24-37" name="__codelineno-24-37" href="#__codelineno-24-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>
9277
- <a id="__codelineno-24-38" name="__codelineno-24-38" href="#__codelineno-24-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>
9278
- <a id="__codelineno-24-39" name="__codelineno-24-39" href="#__codelineno-24-39"></a> <span class="n">switch</span> <span class="o">=</span> <span class="n">Device</span><span class="p">(</span>
9279
- <a id="__codelineno-24-40" name="__codelineno-24-40" href="#__codelineno-24-40"></a> <span class="n">device_type</span><span class="o">=</span><span class="n">switch_model</span><span class="p">,</span>
9280
- <a id="__codelineno-24-41" name="__codelineno-24-41" href="#__codelineno-24-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>
9281
- <a id="__codelineno-24-42" name="__codelineno-24-42" href="#__codelineno-24-42"></a> <span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">,</span>
9282
- <a id="__codelineno-24-43" name="__codelineno-24-43" href="#__codelineno-24-43"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
9283
- <a id="__codelineno-24-44" name="__codelineno-24-44" href="#__codelineno-24-44"></a> <span class="n">role</span><span class="o">=</span><span class="n">switch_role</span><span class="p">,</span>
9284
- <a id="__codelineno-24-45" name="__codelineno-24-45" href="#__codelineno-24-45"></a> <span class="p">)</span>
9285
- <a id="__codelineno-24-46" name="__codelineno-24-46" href="#__codelineno-24-46"></a> <span class="n">switch</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
9286
- <a id="__codelineno-24-47" name="__codelineno-24-47" href="#__codelineno-24-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>
9287
- <a id="__codelineno-24-48" name="__codelineno-24-48" href="#__codelineno-24-48"></a>
9288
- <a id="__codelineno-24-49" name="__codelineno-24-49" href="#__codelineno-24-49"></a> <span class="c1"># Generate a CSV table of new devices</span>
9289
- <a id="__codelineno-24-50" name="__codelineno-24-50" href="#__codelineno-24-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>
9290
- <a id="__codelineno-24-51" name="__codelineno-24-51" href="#__codelineno-24-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>
9291
- <a id="__codelineno-24-52" name="__codelineno-24-52" href="#__codelineno-24-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>
9292
- <a id="__codelineno-24-53" name="__codelineno-24-53" href="#__codelineno-24-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>
9293
- <a id="__codelineno-24-54" name="__codelineno-24-54" href="#__codelineno-24-54"></a>
9294
- <a id="__codelineno-24-55" name="__codelineno-24-55" href="#__codelineno-24-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>
9295
- <a id="__codelineno-24-56" name="__codelineno-24-56" href="#__codelineno-24-56"></a>
9296
- <a id="__codelineno-24-57" name="__codelineno-24-57" href="#__codelineno-24-57"></a>
9297
- <a id="__codelineno-24-58" name="__codelineno-24-58" href="#__codelineno-24-58"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">NewBranch</span><span class="p">)</span>
10059
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span>
10060
+ <a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>
10061
+ <a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span><span class="p">,</span> <span class="n">register_jobs</span>
10062
+ <a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-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>
10063
+ <a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-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>
10064
+ <a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a>
10065
+ <a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="k">class</span> <span class="nc">NewBranch</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
10066
+ <a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
10067
+ <a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-9"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;New Branch&quot;</span>
10068
+ <a id="__codelineno-26-10" name="__codelineno-26-10" href="#__codelineno-26-10"></a> <span class="n">description</span> <span class="o">=</span> <span class="s2">&quot;Provision a new branch location&quot;</span>
10069
+ <a id="__codelineno-26-11" name="__codelineno-26-11" href="#__codelineno-26-11"></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>
10070
+ <a id="__codelineno-26-12" name="__codelineno-26-12" href="#__codelineno-26-12"></a>
10071
+ <a id="__codelineno-26-13" name="__codelineno-26-13" href="#__codelineno-26-13"></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>
10072
+ <a id="__codelineno-26-14" name="__codelineno-26-14" href="#__codelineno-26-14"></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>
10073
+ <a id="__codelineno-26-15" name="__codelineno-26-15" href="#__codelineno-26-15"></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>
10074
+ <a id="__codelineno-26-16" name="__codelineno-26-16" href="#__codelineno-26-16"></a> <span class="n">switch_model</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span>
10075
+ <a id="__codelineno-26-17" name="__codelineno-26-17" href="#__codelineno-26-17"></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>
10076
+ <a id="__codelineno-26-18" name="__codelineno-26-18" href="#__codelineno-26-18"></a> <span class="p">)</span>
10077
+ <a id="__codelineno-26-19" name="__codelineno-26-19" href="#__codelineno-26-19"></a>
10078
+ <a id="__codelineno-26-20" name="__codelineno-26-20" href="#__codelineno-26-20"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">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> <span class="n">manufacturer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
10079
+ <a id="__codelineno-26-21" name="__codelineno-26-21" href="#__codelineno-26-21"></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>
10080
+ <a id="__codelineno-26-22" name="__codelineno-26-22" href="#__codelineno-26-22"></a>
10081
+ <a id="__codelineno-26-23" name="__codelineno-26-23" href="#__codelineno-26-23"></a> <span class="c1"># Create the new location</span>
10082
+ <a id="__codelineno-26-24" name="__codelineno-26-24" href="#__codelineno-26-24"></a> <span class="n">root_type</span><span class="p">,</span> <span class="n">lt_created</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>
10083
+ <a id="__codelineno-26-25" name="__codelineno-26-25" href="#__codelineno-26-25"></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>
10084
+ <a id="__codelineno-26-26" name="__codelineno-26-26" href="#__codelineno-26-26"></a> <span class="n">root_type</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>
10085
+ <a id="__codelineno-26-27" name="__codelineno-26-27" href="#__codelineno-26-27"></a> <span class="n">location</span> <span class="o">=</span> <span class="n">Location</span><span class="p">(</span>
10086
+ <a id="__codelineno-26-28" name="__codelineno-26-28" href="#__codelineno-26-28"></a> <span class="n">name</span><span class="o">=</span><span class="n">location_name</span><span class="p">,</span>
10087
+ <a id="__codelineno-26-29" name="__codelineno-26-29" href="#__codelineno-26-29"></a> <span class="n">location_type</span><span class="o">=</span><span class="n">root_type</span><span class="p">,</span>
10088
+ <a id="__codelineno-26-30" name="__codelineno-26-30" href="#__codelineno-26-30"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
10089
+ <a id="__codelineno-26-31" name="__codelineno-26-31" href="#__codelineno-26-31"></a> <span class="p">)</span>
10090
+ <a id="__codelineno-26-32" name="__codelineno-26-32" href="#__codelineno-26-32"></a> <span class="n">location</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
10091
+ <a id="__codelineno-26-33" name="__codelineno-26-33" href="#__codelineno-26-33"></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>
10092
+ <a id="__codelineno-26-34" name="__codelineno-26-34" href="#__codelineno-26-34"></a>
10093
+ <a id="__codelineno-26-35" name="__codelineno-26-35" href="#__codelineno-26-35"></a> <span class="c1"># Create access switches</span>
10094
+ <a id="__codelineno-26-36" name="__codelineno-26-36" href="#__codelineno-26-36"></a> <span class="n">switch_role</span><span class="p">,</span> <span class="n">r_created</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_or_create</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>
10095
+ <a id="__codelineno-26-37" name="__codelineno-26-37" href="#__codelineno-26-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>
10096
+ <a id="__codelineno-26-38" name="__codelineno-26-38" href="#__codelineno-26-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>
10097
+ <a id="__codelineno-26-39" name="__codelineno-26-39" href="#__codelineno-26-39"></a> <span class="n">switch</span> <span class="o">=</span> <span class="n">Device</span><span class="p">(</span>
10098
+ <a id="__codelineno-26-40" name="__codelineno-26-40" href="#__codelineno-26-40"></a> <span class="n">device_type</span><span class="o">=</span><span class="n">switch_model</span><span class="p">,</span>
10099
+ <a id="__codelineno-26-41" name="__codelineno-26-41" href="#__codelineno-26-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>
10100
+ <a id="__codelineno-26-42" name="__codelineno-26-42" href="#__codelineno-26-42"></a> <span class="n">location</span><span class="o">=</span><span class="n">location</span><span class="p">,</span>
10101
+ <a id="__codelineno-26-43" name="__codelineno-26-43" href="#__codelineno-26-43"></a> <span class="n">status</span><span class="o">=</span><span class="n">STATUS_PLANNED</span><span class="p">,</span>
10102
+ <a id="__codelineno-26-44" name="__codelineno-26-44" href="#__codelineno-26-44"></a> <span class="n">role</span><span class="o">=</span><span class="n">switch_role</span><span class="p">,</span>
10103
+ <a id="__codelineno-26-45" name="__codelineno-26-45" href="#__codelineno-26-45"></a> <span class="p">)</span>
10104
+ <a id="__codelineno-26-46" name="__codelineno-26-46" href="#__codelineno-26-46"></a> <span class="n">switch</span><span class="o">.</span><span class="n">validated_save</span><span class="p">()</span>
10105
+ <a id="__codelineno-26-47" name="__codelineno-26-47" href="#__codelineno-26-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>
10106
+ <a id="__codelineno-26-48" name="__codelineno-26-48" href="#__codelineno-26-48"></a>
10107
+ <a id="__codelineno-26-49" name="__codelineno-26-49" href="#__codelineno-26-49"></a> <span class="c1"># Generate a CSV table of new devices</span>
10108
+ <a id="__codelineno-26-50" name="__codelineno-26-50" href="#__codelineno-26-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>
10109
+ <a id="__codelineno-26-51" name="__codelineno-26-51" href="#__codelineno-26-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>
10110
+ <a id="__codelineno-26-52" name="__codelineno-26-52" href="#__codelineno-26-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>
10111
+ <a id="__codelineno-26-53" name="__codelineno-26-53" href="#__codelineno-26-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>
10112
+ <a id="__codelineno-26-54" name="__codelineno-26-54" href="#__codelineno-26-54"></a>
10113
+ <a id="__codelineno-26-55" name="__codelineno-26-55" href="#__codelineno-26-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>
10114
+ <a id="__codelineno-26-56" name="__codelineno-26-56" href="#__codelineno-26-56"></a>
10115
+ <a id="__codelineno-26-57" name="__codelineno-26-57" href="#__codelineno-26-57"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">NewBranch</span><span class="p">)</span>
9298
10116
  </code></pre></div>
9299
10117
  <h3 id="device-validation">Device validation<a class="headerlink" href="#device-validation" title="Permanent link">&para;</a></h3>
9300
10118
  <p>A job to perform various validation of Device data in Nautobot. As this job does not require any user input, it does not define any variables.</p>
9301
- <div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
9302
- <a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-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>
9303
- <a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
9304
- <a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a>
9305
- <a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a>
9306
- <a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-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>
9307
- <a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-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>
9308
- <a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a>
9309
- <a id="__codelineno-25-9" name="__codelineno-25-9" href="#__codelineno-25-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>
9310
- <a id="__codelineno-25-10" name="__codelineno-25-10" href="#__codelineno-25-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>
9311
- <a id="__codelineno-25-11" name="__codelineno-25-11" href="#__codelineno-25-11"></a>
9312
- <a id="__codelineno-25-12" name="__codelineno-25-12" href="#__codelineno-25-12"></a> <span class="c1"># Check that every console port for every active device has a connection defined.</span>
9313
- <a id="__codelineno-25-13" name="__codelineno-25-13" href="#__codelineno-25-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>
9314
- <a id="__codelineno-25-14" name="__codelineno-25-14" href="#__codelineno-25-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>
9315
- <a id="__codelineno-25-15" name="__codelineno-25-15" href="#__codelineno-25-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>
9316
- <a id="__codelineno-25-16" name="__codelineno-25-16" href="#__codelineno-25-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>
9317
- <a id="__codelineno-25-17" name="__codelineno-25-17" href="#__codelineno-25-17"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
9318
- <a id="__codelineno-25-18" name="__codelineno-25-18" href="#__codelineno-25-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>
9319
- <a id="__codelineno-25-19" name="__codelineno-25-19" href="#__codelineno-25-19"></a> <span class="p">)</span>
9320
- <a id="__codelineno-25-20" name="__codelineno-25-20" href="#__codelineno-25-20"></a> <span class="k">else</span><span class="p">:</span>
9321
- <a id="__codelineno-25-21" name="__codelineno-25-21" href="#__codelineno-25-21"></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>
9322
- <a id="__codelineno-25-22" name="__codelineno-25-22" href="#__codelineno-25-22"></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>
9323
- <a id="__codelineno-25-23" name="__codelineno-25-23" href="#__codelineno-25-23"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
9324
- <a id="__codelineno-25-24" name="__codelineno-25-24" href="#__codelineno-25-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>
9325
- <a id="__codelineno-25-25" name="__codelineno-25-25" href="#__codelineno-25-25"></a> <span class="p">)</span>
9326
- <a id="__codelineno-25-26" name="__codelineno-25-26" href="#__codelineno-25-26"></a>
9327
- <a id="__codelineno-25-27" name="__codelineno-25-27" href="#__codelineno-25-27"></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>
9328
- <a id="__codelineno-25-28" name="__codelineno-25-28" href="#__codelineno-25-28"></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>
9329
- <a id="__codelineno-25-29" name="__codelineno-25-29" href="#__codelineno-25-29"></a>
9330
- <a id="__codelineno-25-30" name="__codelineno-25-30" href="#__codelineno-25-30"></a> <span class="c1"># Check that every active device has at least two connected power supplies.</span>
9331
- <a id="__codelineno-25-31" name="__codelineno-25-31" href="#__codelineno-25-31"></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>
9332
- <a id="__codelineno-25-32" name="__codelineno-25-32" href="#__codelineno-25-32"></a> <span class="n">connected_ports</span> <span class="o">=</span> <span class="mi">0</span>
9333
- <a id="__codelineno-25-33" name="__codelineno-25-33" href="#__codelineno-25-33"></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>
9334
- <a id="__codelineno-25-34" name="__codelineno-25-34" href="#__codelineno-25-34"></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>
9335
- <a id="__codelineno-25-35" name="__codelineno-25-35" href="#__codelineno-25-35"></a> <span class="n">connected_ports</span> <span class="o">+=</span> <span class="mi">1</span>
9336
- <a id="__codelineno-25-36" name="__codelineno-25-36" href="#__codelineno-25-36"></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>
9337
- <a id="__codelineno-25-37" name="__codelineno-25-37" href="#__codelineno-25-37"></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>
9338
- <a id="__codelineno-25-38" name="__codelineno-25-38" href="#__codelineno-25-38"></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>
9339
- <a id="__codelineno-25-39" name="__codelineno-25-39" href="#__codelineno-25-39"></a> <span class="n">connected_ports</span><span class="p">,</span>
9340
- <a id="__codelineno-25-40" name="__codelineno-25-40" href="#__codelineno-25-40"></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>
9341
- <a id="__codelineno-25-41" name="__codelineno-25-41" href="#__codelineno-25-41"></a> <span class="p">)</span>
9342
- <a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a> <span class="k">else</span><span class="p">:</span>
9343
- <a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></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>
9344
- <a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a>
9345
- <a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
9346
- <a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_console_connection</span><span class="p">()</span>
9347
- <a id="__codelineno-25-47" name="__codelineno-25-47" href="#__codelineno-25-47"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_power_connections</span><span class="p">()</span>
9348
- <a id="__codelineno-25-48" name="__codelineno-25-48" href="#__codelineno-25-48"></a>
9349
- <a id="__codelineno-25-49" name="__codelineno-25-49" href="#__codelineno-25-49"></a>
9350
- <a id="__codelineno-25-50" name="__codelineno-25-50" href="#__codelineno-25-50"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">DeviceConnectionsReport</span><span class="p">)</span>
10119
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
10120
+ <a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">ConsolePort</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">PowerPort</span>
10121
+ <a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
10122
+ <a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>
10123
+ <a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>
10124
+ <a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-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>
10125
+ <a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-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>
10126
+ <a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>
10127
+ <a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-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>
10128
+ <a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-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>
10129
+ <a id="__codelineno-27-11" name="__codelineno-27-11" href="#__codelineno-27-11"></a>
10130
+ <a id="__codelineno-27-12" name="__codelineno-27-12" href="#__codelineno-27-12"></a> <span class="c1"># Check that every console port for every active device has a connection defined.</span>
10131
+ <a id="__codelineno-27-13" name="__codelineno-27-13" href="#__codelineno-27-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>
10132
+ <a id="__codelineno-27-14" name="__codelineno-27-14" href="#__codelineno-27-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>
10133
+ <a id="__codelineno-27-15" name="__codelineno-27-15" href="#__codelineno-27-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>
10134
+ <a id="__codelineno-27-16" name="__codelineno-27-16" href="#__codelineno-27-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>
10135
+ <a id="__codelineno-27-17" name="__codelineno-27-17" href="#__codelineno-27-17"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
10136
+ <a id="__codelineno-27-18" name="__codelineno-27-18" href="#__codelineno-27-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>
10137
+ <a id="__codelineno-27-19" name="__codelineno-27-19" href="#__codelineno-27-19"></a> <span class="p">)</span>
10138
+ <a id="__codelineno-27-20" name="__codelineno-27-20" href="#__codelineno-27-20"></a> <span class="k">else</span><span class="p">:</span>
10139
+ <a id="__codelineno-27-21" name="__codelineno-27-21" href="#__codelineno-27-21"></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>
10140
+ <a id="__codelineno-27-22" name="__codelineno-27-22" href="#__codelineno-27-22"></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>
10141
+ <a id="__codelineno-27-23" name="__codelineno-27-23" href="#__codelineno-27-23"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
10142
+ <a id="__codelineno-27-24" name="__codelineno-27-24" href="#__codelineno-27-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>
10143
+ <a id="__codelineno-27-25" name="__codelineno-27-25" href="#__codelineno-27-25"></a> <span class="p">)</span>
10144
+ <a id="__codelineno-27-26" name="__codelineno-27-26" href="#__codelineno-27-26"></a>
10145
+ <a id="__codelineno-27-27" name="__codelineno-27-27" href="#__codelineno-27-27"></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>
10146
+ <a id="__codelineno-27-28" name="__codelineno-27-28" href="#__codelineno-27-28"></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>
10147
+ <a id="__codelineno-27-29" name="__codelineno-27-29" href="#__codelineno-27-29"></a>
10148
+ <a id="__codelineno-27-30" name="__codelineno-27-30" href="#__codelineno-27-30"></a> <span class="c1"># Check that every active device has at least two connected power supplies.</span>
10149
+ <a id="__codelineno-27-31" name="__codelineno-27-31" href="#__codelineno-27-31"></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>
10150
+ <a id="__codelineno-27-32" name="__codelineno-27-32" href="#__codelineno-27-32"></a> <span class="n">connected_ports</span> <span class="o">=</span> <span class="mi">0</span>
10151
+ <a id="__codelineno-27-33" name="__codelineno-27-33" href="#__codelineno-27-33"></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>
10152
+ <a id="__codelineno-27-34" name="__codelineno-27-34" href="#__codelineno-27-34"></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>
10153
+ <a id="__codelineno-27-35" name="__codelineno-27-35" href="#__codelineno-27-35"></a> <span class="n">connected_ports</span> <span class="o">+=</span> <span class="mi">1</span>
10154
+ <a id="__codelineno-27-36" name="__codelineno-27-36" href="#__codelineno-27-36"></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>
10155
+ <a id="__codelineno-27-37" name="__codelineno-27-37" href="#__codelineno-27-37"></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>
10156
+ <a id="__codelineno-27-38" name="__codelineno-27-38" href="#__codelineno-27-38"></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>
10157
+ <a id="__codelineno-27-39" name="__codelineno-27-39" href="#__codelineno-27-39"></a> <span class="n">connected_ports</span><span class="p">,</span>
10158
+ <a id="__codelineno-27-40" name="__codelineno-27-40" href="#__codelineno-27-40"></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>
10159
+ <a id="__codelineno-27-41" name="__codelineno-27-41" href="#__codelineno-27-41"></a> <span class="p">)</span>
10160
+ <a id="__codelineno-27-42" name="__codelineno-27-42" href="#__codelineno-27-42"></a> <span class="k">else</span><span class="p">:</span>
10161
+ <a id="__codelineno-27-43" name="__codelineno-27-43" href="#__codelineno-27-43"></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>
10162
+ <a id="__codelineno-27-44" name="__codelineno-27-44" href="#__codelineno-27-44"></a>
10163
+ <a id="__codelineno-27-45" name="__codelineno-27-45" href="#__codelineno-27-45"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
10164
+ <a id="__codelineno-27-46" name="__codelineno-27-46" href="#__codelineno-27-46"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_console_connection</span><span class="p">()</span>
10165
+ <a id="__codelineno-27-47" name="__codelineno-27-47" href="#__codelineno-27-47"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_power_connections</span><span class="p">()</span>
10166
+ <a id="__codelineno-27-48" name="__codelineno-27-48" href="#__codelineno-27-48"></a>
10167
+ <a id="__codelineno-27-49" name="__codelineno-27-49" href="#__codelineno-27-49"></a>
10168
+ <a id="__codelineno-27-50" name="__codelineno-27-50" href="#__codelineno-27-50"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">DeviceConnectionsReport</span><span class="p">)</span>
9351
10169
  </code></pre></div>
9352
10170
  <h2 id="job-button-receivers">Job Button Receivers<a class="headerlink" href="#job-button-receivers" title="Permanent link">&para;</a></h2>
9353
10171
  <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>
@@ -9361,58 +10179,58 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9361
10179
  <li><code>obj</code> - An instance of the object where the button was pressed</li>
9362
10180
  </ol>
9363
10181
  <h3 id="example-job-button-receiver">Example Job Button Receiver<a class="headerlink" href="#example-job-button-receiver" title="Permanent link">&para;</a></h3>
9364
- <div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
9365
- <a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>
9366
- <a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>
9367
- <a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-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>
9368
- <a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9369
- <a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Simple Job Button Receiver&quot;</span>
9370
- <a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a>
9371
- <a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-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>
9372
- <a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-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>
9373
- <a id="__codelineno-26-10" name="__codelineno-26-10" href="#__codelineno-26-10"></a> <span class="c1"># Add job logic here</span>
9374
- <a id="__codelineno-26-11" name="__codelineno-26-11" href="#__codelineno-26-11"></a>
9375
- <a id="__codelineno-26-12" name="__codelineno-26-12" href="#__codelineno-26-12"></a>
9376
- <a id="__codelineno-26-13" name="__codelineno-26-13" href="#__codelineno-26-13"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleSimpleJobButtonReceiver</span><span class="p">)</span>
10182
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
10183
+ <a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>
10184
+ <a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
10185
+ <a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-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>
10186
+ <a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
10187
+ <a id="__codelineno-28-6" name="__codelineno-28-6" href="#__codelineno-28-6"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Simple Job Button Receiver&quot;</span>
10188
+ <a id="__codelineno-28-7" name="__codelineno-28-7" href="#__codelineno-28-7"></a>
10189
+ <a id="__codelineno-28-8" name="__codelineno-28-8" href="#__codelineno-28-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>
10190
+ <a id="__codelineno-28-9" name="__codelineno-28-9" href="#__codelineno-28-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>
10191
+ <a id="__codelineno-28-10" name="__codelineno-28-10" href="#__codelineno-28-10"></a> <span class="c1"># Add job logic here</span>
10192
+ <a id="__codelineno-28-11" name="__codelineno-28-11" href="#__codelineno-28-11"></a>
10193
+ <a id="__codelineno-28-12" name="__codelineno-28-12" href="#__codelineno-28-12"></a>
10194
+ <a id="__codelineno-28-13" name="__codelineno-28-13" href="#__codelineno-28-13"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleSimpleJobButtonReceiver</span><span class="p">)</span>
9377
10195
  </code></pre></div>
9378
10196
  <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>
9379
10197
  <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>
9380
- <div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
9381
- <a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Location</span>
9382
- <a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
9383
- <a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>
9384
- <a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-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>
9385
- <a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
9386
- <a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Complex Job Button Receiver&quot;</span>
9387
- <a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>
9388
- <a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-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>
9389
- <a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-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>
9390
- <a id="__codelineno-27-11" name="__codelineno-27-11" href="#__codelineno-27-11"></a> <span class="c1"># Run Location Job function</span>
9391
- <a id="__codelineno-27-12" name="__codelineno-27-12" href="#__codelineno-27-12"></a>
9392
- <a id="__codelineno-27-13" name="__codelineno-27-13" href="#__codelineno-27-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>
9393
- <a id="__codelineno-27-14" name="__codelineno-27-14" href="#__codelineno-27-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>
9394
- <a id="__codelineno-27-15" name="__codelineno-27-15" href="#__codelineno-27-15"></a> <span class="c1"># Run Device Job function</span>
9395
- <a id="__codelineno-27-16" name="__codelineno-27-16" href="#__codelineno-27-16"></a>
9396
- <a id="__codelineno-27-17" name="__codelineno-27-17" href="#__codelineno-27-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>
9397
- <a id="__codelineno-27-18" name="__codelineno-27-18" href="#__codelineno-27-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>
9398
- <a id="__codelineno-27-19" name="__codelineno-27-19" href="#__codelineno-27-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>
9399
- <a id="__codelineno-27-20" name="__codelineno-27-20" href="#__codelineno-27-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>
9400
- <a id="__codelineno-27-21" name="__codelineno-27-21" href="#__codelineno-27-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>
9401
- <a id="__codelineno-27-22" name="__codelineno-27-22" href="#__codelineno-27-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>
9402
- <a id="__codelineno-27-23" name="__codelineno-27-23" href="#__codelineno-27-23"></a> <span class="k">else</span><span class="p">:</span>
9403
- <a id="__codelineno-27-24" name="__codelineno-27-24" href="#__codelineno-27-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>
9404
- <a id="__codelineno-27-25" name="__codelineno-27-25" href="#__codelineno-27-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>
9405
- <a id="__codelineno-27-26" name="__codelineno-27-26" href="#__codelineno-27-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>
9406
- <a id="__codelineno-27-27" name="__codelineno-27-27" href="#__codelineno-27-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>
9407
- <a id="__codelineno-27-28" name="__codelineno-27-28" href="#__codelineno-27-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>
9408
- <a id="__codelineno-27-29" name="__codelineno-27-29" href="#__codelineno-27-29"></a> <span class="k">else</span><span class="p">:</span>
9409
- <a id="__codelineno-27-30" name="__codelineno-27-30" href="#__codelineno-27-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>
9410
- <a id="__codelineno-27-31" name="__codelineno-27-31" href="#__codelineno-27-31"></a> <span class="k">else</span><span class="p">:</span>
9411
- <a id="__codelineno-27-32" name="__codelineno-27-32" href="#__codelineno-27-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>
9412
- <a id="__codelineno-27-33" name="__codelineno-27-33" href="#__codelineno-27-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>
9413
- <a id="__codelineno-27-34" name="__codelineno-27-34" href="#__codelineno-27-34"></a>
9414
- <a id="__codelineno-27-35" name="__codelineno-27-35" href="#__codelineno-27-35"></a>
9415
- <a id="__codelineno-27-36" name="__codelineno-27-36" href="#__codelineno-27-36"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleComplexJobButtonReceiver</span><span class="p">)</span>
10198
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
10199
+ <a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-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>
10200
+ <a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a>
10201
+ <a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a>
10202
+ <a id="__codelineno-29-5" name="__codelineno-29-5" href="#__codelineno-29-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>
10203
+ <a id="__codelineno-29-6" name="__codelineno-29-6" href="#__codelineno-29-6"></a> <span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
10204
+ <a id="__codelineno-29-7" name="__codelineno-29-7" href="#__codelineno-29-7"></a> <span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Example Complex Job Button Receiver&quot;</span>
10205
+ <a id="__codelineno-29-8" name="__codelineno-29-8" href="#__codelineno-29-8"></a>
10206
+ <a id="__codelineno-29-9" name="__codelineno-29-9" href="#__codelineno-29-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>
10207
+ <a id="__codelineno-29-10" name="__codelineno-29-10" href="#__codelineno-29-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>
10208
+ <a id="__codelineno-29-11" name="__codelineno-29-11" href="#__codelineno-29-11"></a> <span class="c1"># Run Location Job function</span>
10209
+ <a id="__codelineno-29-12" name="__codelineno-29-12" href="#__codelineno-29-12"></a>
10210
+ <a id="__codelineno-29-13" name="__codelineno-29-13" href="#__codelineno-29-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>
10211
+ <a id="__codelineno-29-14" name="__codelineno-29-14" href="#__codelineno-29-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>
10212
+ <a id="__codelineno-29-15" name="__codelineno-29-15" href="#__codelineno-29-15"></a> <span class="c1"># Run Device Job function</span>
10213
+ <a id="__codelineno-29-16" name="__codelineno-29-16" href="#__codelineno-29-16"></a>
10214
+ <a id="__codelineno-29-17" name="__codelineno-29-17" href="#__codelineno-29-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>
10215
+ <a id="__codelineno-29-18" name="__codelineno-29-18" href="#__codelineno-29-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>
10216
+ <a id="__codelineno-29-19" name="__codelineno-29-19" href="#__codelineno-29-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>
10217
+ <a id="__codelineno-29-20" name="__codelineno-29-20" href="#__codelineno-29-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>
10218
+ <a id="__codelineno-29-21" name="__codelineno-29-21" href="#__codelineno-29-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>
10219
+ <a id="__codelineno-29-22" name="__codelineno-29-22" href="#__codelineno-29-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>
10220
+ <a id="__codelineno-29-23" name="__codelineno-29-23" href="#__codelineno-29-23"></a> <span class="k">else</span><span class="p">:</span>
10221
+ <a id="__codelineno-29-24" name="__codelineno-29-24" href="#__codelineno-29-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>
10222
+ <a id="__codelineno-29-25" name="__codelineno-29-25" href="#__codelineno-29-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>
10223
+ <a id="__codelineno-29-26" name="__codelineno-29-26" href="#__codelineno-29-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>
10224
+ <a id="__codelineno-29-27" name="__codelineno-29-27" href="#__codelineno-29-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>
10225
+ <a id="__codelineno-29-28" name="__codelineno-29-28" href="#__codelineno-29-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>
10226
+ <a id="__codelineno-29-29" name="__codelineno-29-29" href="#__codelineno-29-29"></a> <span class="k">else</span><span class="p">:</span>
10227
+ <a id="__codelineno-29-30" name="__codelineno-29-30" href="#__codelineno-29-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>
10228
+ <a id="__codelineno-29-31" name="__codelineno-29-31" href="#__codelineno-29-31"></a> <span class="k">else</span><span class="p">:</span>
10229
+ <a id="__codelineno-29-32" name="__codelineno-29-32" href="#__codelineno-29-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>
10230
+ <a id="__codelineno-29-33" name="__codelineno-29-33" href="#__codelineno-29-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>
10231
+ <a id="__codelineno-29-34" name="__codelineno-29-34" href="#__codelineno-29-34"></a>
10232
+ <a id="__codelineno-29-35" name="__codelineno-29-35" href="#__codelineno-29-35"></a>
10233
+ <a id="__codelineno-29-36" name="__codelineno-29-36" href="#__codelineno-29-36"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleComplexJobButtonReceiver</span><span class="p">)</span>
9416
10234
  </code></pre></div>
9417
10235
  <h2 id="job-hook-receivers">Job Hook Receivers<a class="headerlink" href="#job-hook-receivers" title="Permanent link">&para;</a></h2>
9418
10236
  <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>
@@ -9425,40 +10243,40 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9425
10243
  <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>
9426
10244
  </div>
9427
10245
  <h3 id="example-job-hook-receiver">Example Job Hook Receiver<a class="headerlink" href="#example-job-hook-receiver" title="Permanent link">&para;</a></h3>
9428
- <div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
9429
- <a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.choices</span> <span class="kn">import</span> <span class="n">ObjectChangeActionChoices</span>
9430
- <a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
9431
- <a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a>
9432
- <a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-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>
9433
- <a id="__codelineno-28-6" name="__codelineno-28-6" href="#__codelineno-28-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>
9434
- <a id="__codelineno-28-7" name="__codelineno-28-7" href="#__codelineno-28-7"></a> <span class="c1"># return on delete action</span>
9435
- <a id="__codelineno-28-8" name="__codelineno-28-8" href="#__codelineno-28-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>
9436
- <a id="__codelineno-28-9" name="__codelineno-28-9" href="#__codelineno-28-9"></a> <span class="k">return</span>
9437
- <a id="__codelineno-28-10" name="__codelineno-28-10" href="#__codelineno-28-10"></a>
9438
- <a id="__codelineno-28-11" name="__codelineno-28-11" href="#__codelineno-28-11"></a> <span class="c1"># log diff output</span>
9439
- <a id="__codelineno-28-12" name="__codelineno-28-12" href="#__codelineno-28-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>
9440
- <a id="__codelineno-28-13" name="__codelineno-28-13" href="#__codelineno-28-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>
9441
- <a id="__codelineno-28-14" name="__codelineno-28-14" href="#__codelineno-28-14"></a>
9442
- <a id="__codelineno-28-15" name="__codelineno-28-15" href="#__codelineno-28-15"></a> <span class="c1"># validate changes to serial field</span>
9443
- <a id="__codelineno-28-16" name="__codelineno-28-16" href="#__codelineno-28-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>
9444
- <a id="__codelineno-28-17" name="__codelineno-28-17" href="#__codelineno-28-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>
9445
- <a id="__codelineno-28-18" name="__codelineno-28-18" href="#__codelineno-28-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>
9446
- <a id="__codelineno-28-19" name="__codelineno-28-19" href="#__codelineno-28-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>
9447
- <a id="__codelineno-28-20" name="__codelineno-28-20" href="#__codelineno-28-20"></a>
9448
- <a id="__codelineno-28-21" name="__codelineno-28-21" href="#__codelineno-28-21"></a> <span class="c1"># Check the new serial is valid and revert if necessary</span>
9449
- <a id="__codelineno-28-22" name="__codelineno-28-22" href="#__codelineno-28-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>
9450
- <a id="__codelineno-28-23" name="__codelineno-28-23" href="#__codelineno-28-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>
9451
- <a id="__codelineno-28-24" name="__codelineno-28-24" href="#__codelineno-28-24"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
9452
- <a id="__codelineno-28-25" name="__codelineno-28-25" href="#__codelineno-28-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>
9453
- <a id="__codelineno-28-26" name="__codelineno-28-26" href="#__codelineno-28-26"></a>
9454
- <a id="__codelineno-28-27" name="__codelineno-28-27" href="#__codelineno-28-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>
9455
- <a id="__codelineno-28-28" name="__codelineno-28-28" href="#__codelineno-28-28"></a>
9456
- <a id="__codelineno-28-29" name="__codelineno-28-29" href="#__codelineno-28-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>
9457
- <a id="__codelineno-28-30" name="__codelineno-28-30" href="#__codelineno-28-30"></a> <span class="c1"># add business logic to validate serial</span>
9458
- <a id="__codelineno-28-31" name="__codelineno-28-31" href="#__codelineno-28-31"></a> <span class="k">return</span> <span class="kc">False</span>
9459
- <a id="__codelineno-28-32" name="__codelineno-28-32" href="#__codelineno-28-32"></a>
9460
- <a id="__codelineno-28-33" name="__codelineno-28-33" href="#__codelineno-28-33"></a>
9461
- <a id="__codelineno-28-34" name="__codelineno-28-34" href="#__codelineno-28-34"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleJobHookReceiver</span><span class="p">)</span>
10246
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
10247
+ <a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.choices</span> <span class="kn">import</span> <span class="n">ObjectChangeActionChoices</span>
10248
+ <a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a>
10249
+ <a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a>
10250
+ <a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-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>
10251
+ <a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-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>
10252
+ <a id="__codelineno-30-7" name="__codelineno-30-7" href="#__codelineno-30-7"></a> <span class="c1"># return on delete action</span>
10253
+ <a id="__codelineno-30-8" name="__codelineno-30-8" href="#__codelineno-30-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>
10254
+ <a id="__codelineno-30-9" name="__codelineno-30-9" href="#__codelineno-30-9"></a> <span class="k">return</span>
10255
+ <a id="__codelineno-30-10" name="__codelineno-30-10" href="#__codelineno-30-10"></a>
10256
+ <a id="__codelineno-30-11" name="__codelineno-30-11" href="#__codelineno-30-11"></a> <span class="c1"># log diff output</span>
10257
+ <a id="__codelineno-30-12" name="__codelineno-30-12" href="#__codelineno-30-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>
10258
+ <a id="__codelineno-30-13" name="__codelineno-30-13" href="#__codelineno-30-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>
10259
+ <a id="__codelineno-30-14" name="__codelineno-30-14" href="#__codelineno-30-14"></a>
10260
+ <a id="__codelineno-30-15" name="__codelineno-30-15" href="#__codelineno-30-15"></a> <span class="c1"># validate changes to serial field</span>
10261
+ <a id="__codelineno-30-16" name="__codelineno-30-16" href="#__codelineno-30-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>
10262
+ <a id="__codelineno-30-17" name="__codelineno-30-17" href="#__codelineno-30-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>
10263
+ <a id="__codelineno-30-18" name="__codelineno-30-18" href="#__codelineno-30-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>
10264
+ <a id="__codelineno-30-19" name="__codelineno-30-19" href="#__codelineno-30-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>
10265
+ <a id="__codelineno-30-20" name="__codelineno-30-20" href="#__codelineno-30-20"></a>
10266
+ <a id="__codelineno-30-21" name="__codelineno-30-21" href="#__codelineno-30-21"></a> <span class="c1"># Check the new serial is valid and revert if necessary</span>
10267
+ <a id="__codelineno-30-22" name="__codelineno-30-22" href="#__codelineno-30-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>
10268
+ <a id="__codelineno-30-23" name="__codelineno-30-23" href="#__codelineno-30-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>
10269
+ <a id="__codelineno-30-24" name="__codelineno-30-24" href="#__codelineno-30-24"></a> <span class="n">changed_object</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
10270
+ <a id="__codelineno-30-25" name="__codelineno-30-25" href="#__codelineno-30-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>
10271
+ <a id="__codelineno-30-26" name="__codelineno-30-26" href="#__codelineno-30-26"></a>
10272
+ <a id="__codelineno-30-27" name="__codelineno-30-27" href="#__codelineno-30-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>
10273
+ <a id="__codelineno-30-28" name="__codelineno-30-28" href="#__codelineno-30-28"></a>
10274
+ <a id="__codelineno-30-29" name="__codelineno-30-29" href="#__codelineno-30-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>
10275
+ <a id="__codelineno-30-30" name="__codelineno-30-30" href="#__codelineno-30-30"></a> <span class="c1"># add business logic to validate serial</span>
10276
+ <a id="__codelineno-30-31" name="__codelineno-30-31" href="#__codelineno-30-31"></a> <span class="k">return</span> <span class="kc">False</span>
10277
+ <a id="__codelineno-30-32" name="__codelineno-30-32" href="#__codelineno-30-32"></a>
10278
+ <a id="__codelineno-30-33" name="__codelineno-30-33" href="#__codelineno-30-33"></a>
10279
+ <a id="__codelineno-30-34" name="__codelineno-30-34" href="#__codelineno-30-34"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleJobHookReceiver</span><span class="p">)</span>
9462
10280
  </code></pre></div>
9463
10281
  <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>
9464
10282
  <p>All <code>JobHookReceiver</code> subclasses must implement a <code>receive_job_hook()</code> method. This method accepts three arguments:</p>
@@ -9563,7 +10381,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9563
10381
 
9564
10382
 
9565
10383
  <a href="https://blog.networktocode.com/blog/tags/nautobot" target="_blank" rel="noopener" title="Network to Code Blog" class="md-social__link">
9566
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M0 64c0-17.7 14.3-32 32-32 229.8 0 416 186.2 416 416 0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96 14.3 96 0 81.7 0 64zm0 352a64 64 0 1 1 128 0 64 64 0 1 1-128 0zm32-256c159.1 0 288 128.9 288 288 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224-17.7 0-32-14.3-32-32s14.3-32 32-32z"/></svg>
10384
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M0 64c0-17.7 14.3-32 32-32 229.8 0 416 186.2 416 416 0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96 14.3 96 0 81.7 0 64zm0 352a64 64 0 1 1 128 0 64 64 0 1 1-128 0zm32-256c159.1 0 288 128.9 288 288 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224-17.7 0-32-14.3-32-32s14.3-32 32-32z"/></svg>
9567
10385
  </a>
9568
10386
 
9569
10387
 
@@ -9571,7 +10389,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9571
10389
 
9572
10390
 
9573
10391
  <a href="https://www.youtube.com/playlist?list=PLjA0bhxgryJ2Ts4GJMDA-tPzVWEncv4pb" target="_blank" rel="noopener" title="Nautobot Videos" class="md-social__link">
9574
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
10392
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
9575
10393
  </a>
9576
10394
 
9577
10395
 
@@ -9579,7 +10397,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9579
10397
 
9580
10398
 
9581
10399
  <a href="https://www.networktocode.com/community/" target="_blank" rel="noopener" title="Network to Code Community" class="md-social__link">
9582
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z"/></svg>
10400
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z"/></svg>
9583
10401
  </a>
9584
10402
 
9585
10403
 
@@ -9587,7 +10405,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9587
10405
 
9588
10406
 
9589
10407
  <a href="https://github.com/nautobot/nautobot" target="_blank" rel="noopener" title="GitHub Repo" class="md-social__link">
9590
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
10408
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
9591
10409
  </a>
9592
10410
 
9593
10411
 
@@ -9595,7 +10413,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
9595
10413
 
9596
10414
 
9597
10415
  <a href="https://twitter.com/networktocode" target="_blank" rel="noopener" title="Network to Code Twitter" class="md-social__link">
9598
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
10416
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
9599
10417
  </a>
9600
10418
 
9601
10419
  </div>