nautobot 2.3.2__py3-none-any.whl → 2.3.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. nautobot/core/tests/runner.py +27 -9
  2. nautobot/core/tests/test_utils.py +13 -0
  3. nautobot/core/utils/lookup.py +7 -1
  4. nautobot/extras/context_managers.py +11 -4
  5. nautobot/extras/jobs.py +0 -1
  6. nautobot/extras/models/groups.py +4 -1
  7. nautobot/extras/tests/test_context_managers.py +33 -14
  8. nautobot/extras/tests/test_dynamicgroups.py +11 -0
  9. nautobot/extras/tests/test_models.py +5 -0
  10. nautobot/extras/tests/test_views.py +1 -0
  11. nautobot/ipam/models.py +4 -0
  12. nautobot/ipam/tests/test_api.py +11 -0
  13. nautobot/project-static/docs/404.html +23 -23
  14. nautobot/project-static/docs/apps/index.html +25 -25
  15. nautobot/project-static/docs/apps/nautobot-apps.html +24 -24
  16. nautobot/project-static/docs/assets/javascripts/bundle.56dfad97.min.js +16 -0
  17. nautobot/project-static/docs/assets/javascripts/bundle.56dfad97.min.js.map +7 -0
  18. nautobot/project-static/docs/assets/javascripts/workers/{search.b8dbb3d2.min.js → search.07f07601.min.js} +1 -1
  19. nautobot/project-static/docs/assets/javascripts/workers/{search.b8dbb3d2.min.js.map → search.07f07601.min.js.map} +1 -1
  20. nautobot/project-static/docs/assets/stylesheets/main.35f28582.min.css +1 -0
  21. nautobot/project-static/docs/assets/stylesheets/main.35f28582.min.css.map +1 -0
  22. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +26 -26
  23. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +26 -26
  24. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +58 -58
  25. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +32 -31
  26. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +31 -31
  27. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +25 -25
  28. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +25 -25
  29. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +30 -30
  30. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +34 -34
  31. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +41 -41
  32. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +48 -48
  33. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +92 -92
  34. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +41 -41
  35. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +85 -85
  36. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +84 -84
  37. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +26 -26
  38. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +28 -28
  39. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +40 -40
  40. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +78 -78
  41. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +77 -77
  42. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +26 -26
  43. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +80 -80
  44. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +67 -67
  45. nautobot/project-static/docs/development/apps/api/configuration-view.html +25 -25
  46. nautobot/project-static/docs/development/apps/api/database-backend-config.html +25 -25
  47. nautobot/project-static/docs/development/apps/api/models/django-admin.html +25 -25
  48. nautobot/project-static/docs/development/apps/api/models/global-search.html +25 -25
  49. nautobot/project-static/docs/development/apps/api/models/graphql.html +25 -25
  50. nautobot/project-static/docs/development/apps/api/models/index.html +25 -25
  51. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +25 -25
  52. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +25 -25
  53. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +25 -25
  54. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +25 -25
  55. nautobot/project-static/docs/development/apps/api/platform-features/index.html +25 -25
  56. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +25 -25
  57. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +25 -25
  58. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +25 -25
  59. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +25 -25
  60. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +25 -25
  61. nautobot/project-static/docs/development/apps/api/prometheus.html +25 -25
  62. nautobot/project-static/docs/development/apps/api/setup.html +25 -25
  63. nautobot/project-static/docs/development/apps/api/testing.html +25 -25
  64. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +25 -25
  65. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +25 -25
  66. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +25 -25
  67. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +25 -25
  68. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +25 -25
  69. nautobot/project-static/docs/development/apps/api/views/base-template.html +25 -25
  70. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +25 -25
  71. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +25 -25
  72. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +25 -25
  73. nautobot/project-static/docs/development/apps/api/views/index.html +25 -25
  74. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +25 -25
  75. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +25 -25
  76. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +25 -25
  77. nautobot/project-static/docs/development/apps/api/views/notes.html +25 -25
  78. nautobot/project-static/docs/development/apps/api/views/rest-api.html +25 -25
  79. nautobot/project-static/docs/development/apps/api/views/urls.html +25 -25
  80. nautobot/project-static/docs/development/apps/index.html +25 -25
  81. nautobot/project-static/docs/development/apps/migration/code-updates.html +25 -25
  82. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +25 -25
  83. nautobot/project-static/docs/development/apps/migration/from-v1.html +25 -25
  84. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +25 -25
  85. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +25 -25
  86. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +25 -25
  87. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +25 -25
  88. nautobot/project-static/docs/development/apps/porting-from-netbox.html +25 -25
  89. nautobot/project-static/docs/development/core/application-registry.html +25 -25
  90. nautobot/project-static/docs/development/core/best-practices.html +25 -25
  91. nautobot/project-static/docs/development/core/bootstrap-ui.html +25 -25
  92. nautobot/project-static/docs/development/core/caching.html +25 -25
  93. nautobot/project-static/docs/development/core/controllers.html +25 -25
  94. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +25 -25
  95. nautobot/project-static/docs/development/core/generic-views.html +25 -25
  96. nautobot/project-static/docs/development/core/getting-started.html +25 -25
  97. nautobot/project-static/docs/development/core/homepage.html +25 -25
  98. nautobot/project-static/docs/development/core/index.html +25 -25
  99. nautobot/project-static/docs/development/core/model-checklist.html +25 -25
  100. nautobot/project-static/docs/development/core/model-features.html +25 -25
  101. nautobot/project-static/docs/development/core/natural-keys.html +25 -25
  102. nautobot/project-static/docs/development/core/navigation-menu.html +25 -25
  103. nautobot/project-static/docs/development/core/release-checklist.html +25 -25
  104. nautobot/project-static/docs/development/core/role-internals.html +25 -25
  105. nautobot/project-static/docs/development/core/settings.html +25 -25
  106. nautobot/project-static/docs/development/core/style-guide.html +25 -25
  107. nautobot/project-static/docs/development/core/templates.html +25 -25
  108. nautobot/project-static/docs/development/core/testing.html +25 -25
  109. nautobot/project-static/docs/development/core/user-preferences.html +25 -25
  110. nautobot/project-static/docs/development/index.html +25 -25
  111. nautobot/project-static/docs/development/jobs/index.html +25 -25
  112. nautobot/project-static/docs/development/jobs/migration/from-v1.html +25 -25
  113. nautobot/project-static/docs/index.html +30 -30
  114. nautobot/project-static/docs/overview/application_stack.html +31 -31
  115. nautobot/project-static/docs/overview/design_philosophy.html +25 -25
  116. nautobot/project-static/docs/release-notes/index.html +25 -25
  117. nautobot/project-static/docs/release-notes/version-1.0.html +25 -25
  118. nautobot/project-static/docs/release-notes/version-1.1.html +25 -25
  119. nautobot/project-static/docs/release-notes/version-1.2.html +25 -25
  120. nautobot/project-static/docs/release-notes/version-1.3.html +25 -25
  121. nautobot/project-static/docs/release-notes/version-1.4.html +25 -25
  122. nautobot/project-static/docs/release-notes/version-1.5.html +25 -25
  123. nautobot/project-static/docs/release-notes/version-1.6.html +25 -25
  124. nautobot/project-static/docs/release-notes/version-2.0.html +25 -25
  125. nautobot/project-static/docs/release-notes/version-2.1.html +25 -25
  126. nautobot/project-static/docs/release-notes/version-2.2.html +25 -25
  127. nautobot/project-static/docs/release-notes/version-2.3.html +188 -61
  128. nautobot/project-static/docs/search/search_index.json +1 -1
  129. nautobot/project-static/docs/sitemap.xml +271 -542
  130. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  131. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +25 -25
  132. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +25 -25
  133. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +25 -25
  134. nautobot/project-static/docs/user-guide/administration/configuration/index.html +25 -25
  135. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +25 -25
  136. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +25 -25
  137. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +25 -25
  138. nautobot/project-static/docs/user-guide/administration/guides/caching.html +25 -25
  139. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +25 -25
  140. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +25 -25
  141. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +25 -25
  142. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +25 -25
  143. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +25 -25
  144. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +25 -25
  145. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +25 -25
  146. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +25 -25
  147. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +25 -25
  148. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +25 -25
  149. nautobot/project-static/docs/user-guide/administration/installation/index.html +25 -25
  150. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +25 -25
  151. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +25 -25
  152. nautobot/project-static/docs/user-guide/administration/installation/services.html +25 -25
  153. nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +25 -25
  154. nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +25 -25
  155. nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +25 -25
  156. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +25 -25
  157. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +25 -25
  158. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +25 -25
  159. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +25 -25
  160. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +25 -25
  161. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +25 -25
  162. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +25 -25
  163. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +25 -25
  164. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +25 -25
  165. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +25 -25
  166. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +25 -25
  167. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +25 -25
  168. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +25 -25
  169. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +25 -25
  170. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +25 -25
  171. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +25 -25
  172. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +25 -25
  173. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +25 -25
  174. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +25 -25
  175. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +25 -25
  176. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +25 -25
  177. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +25 -25
  178. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +25 -25
  179. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +25 -25
  180. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +25 -25
  181. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +25 -25
  182. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +25 -25
  183. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +25 -25
  184. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +25 -25
  185. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +25 -25
  186. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +25 -25
  187. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +25 -25
  188. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +25 -25
  189. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +25 -25
  190. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +25 -25
  191. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +25 -25
  192. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +25 -25
  193. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +25 -25
  194. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +25 -25
  195. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +25 -25
  196. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +25 -25
  197. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +25 -25
  198. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +25 -25
  199. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +25 -25
  200. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +25 -25
  201. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +25 -25
  202. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +25 -25
  203. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +25 -25
  204. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +25 -25
  205. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +25 -25
  206. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +25 -25
  207. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +25 -25
  208. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +25 -25
  209. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +25 -25
  210. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +25 -25
  211. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +25 -25
  212. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +25 -25
  213. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +25 -25
  214. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +25 -25
  215. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +25 -25
  216. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +25 -25
  217. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +25 -25
  218. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +25 -25
  219. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +25 -25
  220. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +25 -25
  221. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +25 -25
  222. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +25 -25
  223. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +25 -25
  224. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +25 -25
  225. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +25 -25
  226. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +25 -25
  227. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +25 -25
  228. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +25 -25
  229. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +25 -25
  230. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +25 -25
  231. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +25 -25
  232. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +25 -25
  233. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +25 -25
  234. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +25 -25
  235. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +25 -25
  236. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +25 -25
  237. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +25 -25
  238. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +25 -25
  239. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +25 -25
  240. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +25 -25
  241. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +25 -25
  242. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +25 -25
  243. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +25 -25
  244. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +25 -25
  245. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +25 -25
  246. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +25 -25
  247. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +25 -25
  248. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +25 -25
  249. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +25 -25
  250. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +25 -25
  251. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +25 -25
  252. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +25 -25
  253. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +25 -25
  254. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +25 -25
  255. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +25 -25
  256. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +25 -25
  257. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +25 -25
  258. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +25 -25
  259. nautobot/project-static/docs/user-guide/index.html +25 -25
  260. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +25 -25
  261. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +25 -25
  262. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +25 -25
  263. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +25 -25
  264. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +25 -25
  265. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +25 -25
  266. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +25 -25
  267. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +25 -25
  268. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +25 -25
  269. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +25 -25
  270. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +25 -25
  271. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +25 -25
  272. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +25 -25
  273. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +25 -25
  274. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +25 -25
  275. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +25 -25
  276. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +25 -25
  277. nautobot/project-static/docs/user-guide/platform-functionality/note.html +25 -25
  278. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +25 -25
  279. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +25 -25
  280. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +25 -25
  281. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +25 -25
  282. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +25 -25
  283. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +25 -25
  284. nautobot/project-static/docs/user-guide/platform-functionality/role.html +25 -25
  285. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +25 -25
  286. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +25 -25
  287. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +25 -25
  288. nautobot/project-static/docs/user-guide/platform-functionality/status.html +25 -25
  289. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +25 -25
  290. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +25 -25
  291. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +25 -25
  292. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +25 -25
  293. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +25 -25
  294. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/METADATA +4 -4
  295. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/RECORD +299 -299
  296. nautobot/project-static/docs/assets/javascripts/bundle.fe8b6f2b.min.js +0 -29
  297. nautobot/project-static/docs/assets/javascripts/bundle.fe8b6f2b.min.js.map +0 -7
  298. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +0 -1
  299. nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +0 -1
  300. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/LICENSE.txt +0 -0
  301. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/NOTICE +0 -0
  302. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/WHEEL +0 -0
  303. {nautobot-2.3.2.dist-info → nautobot-2.3.3.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,13 @@
1
1
  import copy
2
2
  import hashlib
3
3
 
4
+ try:
5
+ from coverage import Coverage
6
+
7
+ has_coverage = True
8
+ except ImportError:
9
+ has_coverage = False
10
+
4
11
  from django.conf import settings
5
12
  from django.core.management import call_command
6
13
  from django.db import connections
@@ -49,6 +56,15 @@ class NautobotTestRunner(DiscoverRunner):
49
56
 
50
57
  exclude_tags = ["integration"]
51
58
 
59
+ @classmethod
60
+ def add_arguments(cls, parser):
61
+ super().add_arguments(parser)
62
+ parser.add_argument(
63
+ "--cache-test-fixtures",
64
+ action="store_true",
65
+ help="Save test database to a json fixture file to re-use on subsequent tests.",
66
+ )
67
+
52
68
  def __init__(self, cache_test_fixtures=False, **kwargs):
53
69
  self.cache_test_fixtures = cache_test_fixtures
54
70
 
@@ -64,15 +80,6 @@ class NautobotTestRunner(DiscoverRunner):
64
80
 
65
81
  super().__init__(**kwargs)
66
82
 
67
- @classmethod
68
- def add_arguments(cls, parser):
69
- super().add_arguments(parser)
70
- parser.add_argument(
71
- "--cache-test-fixtures",
72
- action="store_true",
73
- help="Save test database to a json fixture file to re-use on subsequent tests.",
74
- )
75
-
76
83
  def setup_test_environment(self, **kwargs):
77
84
  super().setup_test_environment(**kwargs)
78
85
  # Remove 'testserver' that Django "helpfully" adds automatically to ALLOWED_HOSTS, masking issues like #3065
@@ -91,6 +98,13 @@ class NautobotTestRunner(DiscoverRunner):
91
98
 
92
99
  old_names = []
93
100
 
101
+ # Nautobot specific - disable coverage measurement to improve performance of (slow) database setup
102
+ cov = None
103
+ if has_coverage:
104
+ cov = Coverage.current()
105
+ if cov is not None:
106
+ cov.stop()
107
+
94
108
  for db_name, aliases in test_databases.values():
95
109
  first_alias = None
96
110
  for alias in aliases:
@@ -150,6 +164,10 @@ class NautobotTestRunner(DiscoverRunner):
150
164
  for alias in connections:
151
165
  connections[alias].force_debug_cursor = True
152
166
 
167
+ # Nautobot specific - resume test coverage measurement
168
+ if cov is not None:
169
+ cov.start()
170
+
153
171
  return old_names
154
172
 
155
173
  def teardown_databases(self, old_config, **kwargs):
@@ -234,6 +234,19 @@ class GetFooForModelTest(TestCase):
234
234
  self.assertEqual(lookup.get_model_from_name("dcim.device"), dcim_models.Device)
235
235
  self.assertEqual(lookup.get_model_from_name("dcim.location"), dcim_models.Location)
236
236
 
237
+ def test_get_model_for_view_name(self):
238
+ """
239
+ Test the util function `get_model_for_view_name` returns the appropriate Model, if the colon separated view name provided.
240
+ """
241
+ with self.subTest("Test core view."):
242
+ self.assertEqual(lookup.get_model_for_view_name("dcim:device_list"), dcim_models.Device)
243
+ with self.subTest("Test app view."):
244
+ self.assertEqual(lookup.get_model_for_view_name("plugins:example_app:examplemodel_list"), ExampleModel)
245
+ with self.subTest("Test unexpected view."):
246
+ with self.assertRaises(ValueError) as err:
247
+ lookup.get_model_for_view_name("unknown:plugins:example_app:examplemodel_list")
248
+ self.assertEqual(str(err.exception), "Unexpected View Name: unknown:plugins:example_app:examplemodel_list")
249
+
237
250
 
238
251
  class IsTaggableTest(TestCase):
239
252
  def test_is_taggable_true(self):
@@ -213,7 +213,13 @@ def get_model_for_view_name(view_name):
213
213
  Return the model class associated with the given view_name e.g. "circuits:circuit_detail", "dcim:device_list" and etc.
214
214
  If the app_label or model_name contained by the given view_name is invalid, this will return `None`.
215
215
  """
216
- app_label, model_name = view_name.split(":") # dcim, device_list
216
+ split_view_name = view_name.split(":")
217
+ if len(split_view_name) == 2:
218
+ app_label, model_name = split_view_name # dcim, device_list
219
+ elif len(split_view_name) == 3:
220
+ _, app_label, model_name = split_view_name # plugins, app_name, model_list
221
+ else:
222
+ raise ValueError(f"Unexpected View Name: {view_name}")
217
223
  model_name = model_name.split("_")[0] # device
218
224
 
219
225
  try:
@@ -175,11 +175,12 @@ def web_request_context(
175
175
  :param user: User object
176
176
  :param context_detail: Optional extra details about the transaction (ex: the plugin name that initiated the change)
177
177
  :param change_id: Optional uuid object to uniquely identify the transaction. One will be generated if not supplied
178
- :param context: Optional string value of the generated change log entries' "change_context" field, defaults to ObjectChangeEventContextChoices.CONTEXT_ORM.
179
- Valid choices are in nautobot.extras.choices.ObjectChangeEventContextChoices
178
+ :param context: Optional string value of the generated change log entries' "change_context" field.
179
+ Defaults to `ObjectChangeEventContextChoices.CONTEXT_ORM`.
180
+ Valid choices are in `nautobot.extras.choices.ObjectChangeEventContextChoices`.
180
181
  :param request: Optional web request instance, one will be generated if not supplied
181
182
  """
182
- from nautobot.extras.jobs import enqueue_job_hooks # prevent circular import
183
+ from nautobot.extras.jobs import enqueue_job_hooks, get_jobs # prevent circular import
183
184
 
184
185
  valid_contexts = {
185
186
  ObjectChangeEventContextChoices.CONTEXT_JOB: JobChangeContext,
@@ -202,9 +203,15 @@ def web_request_context(
202
203
  with change_logging(change_context):
203
204
  yield request
204
205
  finally:
206
+ jobs_refreshed = False
205
207
  # enqueue jobhooks and webhooks, use change_context.change_id in case change_id was not supplied
206
208
  for object_change in ObjectChange.objects.filter(request_id=change_context.change_id).iterator():
207
- enqueue_job_hooks(object_change)
209
+ if context != ObjectChangeEventContextChoices.CONTEXT_JOB_HOOK:
210
+ # Make sure JobHooks are up to date (once) before calling them
211
+ if not jobs_refreshed:
212
+ get_jobs(reload=True)
213
+ jobs_refreshed = True
214
+ enqueue_job_hooks(object_change)
208
215
  enqueue_webhooks(object_change)
209
216
 
210
217
 
nautobot/extras/jobs.py CHANGED
@@ -1168,7 +1168,6 @@ def enqueue_job_hooks(object_change):
1168
1168
  job_hooks = JobHook.objects.filter(content_types=content_type, enabled=True, **{action_flag: True})
1169
1169
 
1170
1170
  # Enqueue the jobs related to the job_hooks
1171
- get_jobs(reload=True)
1172
1171
  for job_hook in job_hooks:
1173
1172
  job_model = job_hook.job
1174
1173
  if not job_model.installed or not job_model.enabled:
@@ -251,7 +251,10 @@ class DynamicGroup(PrimaryModel):
251
251
  # Skip filter fields that have methods defined. They are not reversible.
252
252
  if skip_method_filters and filterset_field.method is not None:
253
253
  # Don't skip method fields that also have a "generate_query_" method
254
- if hasattr(filterset, "generate_query_" + filterset_field.method):
254
+ query_attr = (
255
+ filterset_field.method.__name__ if callable(filterset_field.method) else filterset_field.method
256
+ )
257
+ if hasattr(filterset, f"generate_query_{query_attr}"):
255
258
  logger.debug(
256
259
  "Keeping %s for filterform: has a `generate_query_` filter method", filterset_field_name
257
260
  )
@@ -1,3 +1,5 @@
1
+ from unittest import mock
2
+
1
3
  from django.contrib.auth import get_user_model
2
4
  from django.contrib.contenttypes.models import ContentType
3
5
  from django.test import TestCase
@@ -72,7 +74,9 @@ class WebRequestContextTestCase(TestCase):
72
74
  self.assertEqual(oc_list[0].changed_object, location)
73
75
  self.assertEqual(oc_list[0].action, ObjectChangeActionChoices.ACTION_CREATE)
74
76
 
75
- def test_create_then_delete(self):
77
+ @mock.patch("nautobot.extras.jobs.enqueue_job_hooks")
78
+ @mock.patch("nautobot.extras.context_managers.enqueue_webhooks")
79
+ def test_create_then_delete(self, mock_enqueue_webhooks, mock_enqueue_job_hooks):
76
80
  """Test that a create followed by a delete is logged as two changes"""
77
81
  location_type = LocationType.objects.get(name="Campus")
78
82
  location_status = Status.objects.get_for_model(Location).first()
@@ -88,6 +92,8 @@ class WebRequestContextTestCase(TestCase):
88
92
  self.assertEqual(len(oc_list), 2)
89
93
  self.assertEqual(oc_list[0].action, ObjectChangeActionChoices.ACTION_DELETE)
90
94
  self.assertEqual(oc_list[1].action, ObjectChangeActionChoices.ACTION_CREATE)
95
+ mock_enqueue_job_hooks.assert_has_calls([mock.call(oc_list[0]), mock.call(oc_list[1])])
96
+ mock_enqueue_webhooks.assert_has_calls([mock.call(oc_list[0]), mock.call(oc_list[1])])
91
97
 
92
98
  def test_update_then_delete(self):
93
99
  """Test that an update followed by a delete is logged as a single delete"""
@@ -179,21 +185,30 @@ class WebRequestContextTestCase(TestCase):
179
185
  with self.subTest():
180
186
  self.assertEqual(oc_list[0].change_context_detail, "test_change_log_context")
181
187
 
182
- def test_change_webhook_enqueued(self):
188
+ @mock.patch("nautobot.extras.webhooks.process_webhook.apply_async")
189
+ def test_change_webhook_enqueued(self, mock_apply_async):
183
190
  """Test that the webhook resides on the queue"""
184
- # TODO(john): come back to this with a way to actually do it without a running worker
185
- # The celery inspection API expects to be able to communicate with at least 1 running
186
- # worker and there does not appear to be an easy way to look into the queues directly.
187
- # with web_request_context(self.user):
188
- # site = Site(name="Test Site 2")
189
- # site.save()
191
+ with web_request_context(self.user):
192
+ location = Location(
193
+ name="Test Location 2",
194
+ location_type=LocationType.objects.get(name="Campus"),
195
+ status=Status.objects.get_for_model(Location).first(),
196
+ )
197
+ location.save()
190
198
 
191
199
  # Verify that a job was queued for the object creation webhook
192
- # site = Site.objects.get(name="Test Site 2")
193
-
194
- # self.assertEqual(job.args[0], Webhook.objects.get(type_create=True))
195
- # self.assertEqual(job.args[1]["id"], str(site.pk))
196
- # self.assertEqual(job.args[2], "site")
200
+ oc_list = get_changes_for_model(location)
201
+ mock_apply_async.assert_called_once()
202
+ call_args = mock_apply_async.call_args.kwargs["args"]
203
+ self.assertEqual(8, len(call_args), call_args)
204
+ self.assertEqual(call_args[0], Webhook.objects.get(type_create=True).pk)
205
+ self.assertEqual(call_args[1], oc_list[0].object_data_v2)
206
+ self.assertEqual(call_args[2], "location")
207
+ self.assertEqual(call_args[3], "create")
208
+ self.assertIsInstance(call_args[4], str) # str(timezone.now())
209
+ self.assertEqual(call_args[5], self.user.username)
210
+ self.assertEqual(call_args[6], oc_list[0].request_id)
211
+ self.assertEqual(call_args[7], oc_list[0].get_snapshots())
197
212
 
198
213
 
199
214
  class WebRequestContextTransactionTestCase(TransactionTestCase):
@@ -282,7 +297,8 @@ class BulkEditDeleteChangeLogging(TestCase):
282
297
  self.assertIsNone(snapshots["differences"]["removed"])
283
298
  self.assertEqual(snapshots["differences"]["added"]["description"], "changed")
284
299
 
285
- def test_bulk_edit(self):
300
+ @mock.patch("nautobot.extras.jobs.import_jobs")
301
+ def test_bulk_edit(self, mock_import_jobs):
286
302
  """Test that edits to multiple objects are correctly logged"""
287
303
  location_type = LocationType.objects.get(name="Campus")
288
304
  location_status = Status.objects.get_for_model(Location).first()
@@ -309,6 +325,9 @@ class BulkEditDeleteChangeLogging(TestCase):
309
325
  self.assertIsNone(snapshots["differences"]["removed"])
310
326
  self.assertEqual(snapshots["differences"]["added"]["description"], "changed")
311
327
 
328
+ # Check for regression of https://github.com/nautobot/nautobot/issues/6203
329
+ mock_import_jobs.assert_called_once()
330
+
312
331
  def test_bulk_edit_device_type_software_image_file(self):
313
332
  """Test that bulk edits to null does not cause integrity error"""
314
333
  manufacturer = Manufacturer.objects.create(name="Test")
@@ -494,6 +494,17 @@ class DynamicGroupModelTest(DynamicGroupTestBase): # TODO: BaseModelTestCase mi
494
494
  self.assertIsInstance(fields["cluster"], MultiMatchModelMultipleChoiceField)
495
495
  self.assertIsInstance(fields["cluster"].widget, APISelectMultiple)
496
496
 
497
+ def test_map_filter_fields_with_custom_filter_method(self):
498
+ """
499
+ Test that extension_filters with custom methods can be concatenated into `generate_query_{filter_method}`
500
+ and _map_filter_fields method doesn't brake on string concatenation.
501
+ This is a regression test for issue #6184.
502
+ """
503
+ tenant_content_type = ContentType.objects.get_for_model(Tenant)
504
+ # using Tenant as example app has a custom filter with a custom method.
505
+ group = DynamicGroup(name="tenant", content_type=tenant_content_type)
506
+ self.assertIsInstance(group._map_filter_fields, dict)
507
+
497
508
  def test_map_filter_fields_skip_missing(self):
498
509
  """
499
510
  Test that missing fields are skipped in `DynamicGroup._map_filter_fields`
@@ -1091,12 +1091,15 @@ class JobModelTest(ModelTestCases.BaseModelTestCase):
1091
1091
  cls.app_job = JobModel.objects.get(job_class_name="ExampleJob")
1092
1092
 
1093
1093
  def test_job_class(self):
1094
+ self.assertIsNotNone(self.local_job.job_class)
1094
1095
  self.assertEqual(self.local_job.job_class.description, "Validate job import")
1095
1096
 
1097
+ self.assertIsNotNone(self.app_job.job_class)
1096
1098
  self.assertEqual(self.app_job.job_class, ExampleJob)
1097
1099
 
1098
1100
  def test_class_path(self):
1099
1101
  self.assertEqual(self.local_job.class_path, "pass.TestPass")
1102
+ self.assertIsNotNone(self.local_job.job_class)
1100
1103
  self.assertEqual(self.local_job.class_path, self.local_job.job_class.class_path)
1101
1104
 
1102
1105
  self.assertEqual(self.app_job.class_path, "example_app.jobs.ExampleJob")
@@ -1118,6 +1121,7 @@ class JobModelTest(ModelTestCases.BaseModelTestCase):
1118
1121
  self.assertTrue(job_model.enabled)
1119
1122
  else:
1120
1123
  self.assertFalse(job_model.enabled)
1124
+ self.assertIsNotNone(job_model.job_class)
1121
1125
  for field_name in JOB_OVERRIDABLE_FIELDS:
1122
1126
  if field_name == "name" and "duplicate_name" in job_model.job_class.__module__:
1123
1127
  pass # name field for test_duplicate_name jobs tested in test_duplicate_job_name below
@@ -1173,6 +1177,7 @@ class JobModelTest(ModelTestCases.BaseModelTestCase):
1173
1177
  setattr(self.job_containing_sensitive_variables, f"{field_name}_override", False)
1174
1178
  self.job_containing_sensitive_variables.validated_save()
1175
1179
  self.job_containing_sensitive_variables.refresh_from_db()
1180
+ self.assertIsNotNone(self.job_containing_sensitive_variables.job_class)
1176
1181
  for field_name in overridden_attrs:
1177
1182
  self.assertEqual(
1178
1183
  getattr(self.job_containing_sensitive_variables, field_name),
@@ -3008,6 +3008,7 @@ class JobCustomTemplateTestCase(TestCase):
3008
3008
  cls.run_url = reverse("extras:job_run", kwargs={"pk": cls.example_job.pk})
3009
3009
 
3010
3010
  def test_rendering_custom_template(self):
3011
+ self.assertIsNotNone(self.example_job.job_class)
3011
3012
  obj_perm = ObjectPermission(name="Test permission", actions=["view", "run"])
3012
3013
  obj_perm.save()
3013
3014
  obj_perm.users.add(self.user)
nautobot/ipam/models.py CHANGED
@@ -535,6 +535,10 @@ class Prefix(PrimaryModel):
535
535
  def __str__(self):
536
536
  return str(self.prefix)
537
537
 
538
+ @property
539
+ def display(self):
540
+ return f"{self.prefix}: {self.namespace}"
541
+
538
542
  def _deconstruct_prefix(self, prefix):
539
543
  if prefix:
540
544
  if isinstance(prefix, str):
@@ -443,6 +443,17 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
443
443
  for i, p in enumerate(response.data):
444
444
  self.assertEqual(p["prefix"], str(available_prefixes[i]))
445
445
 
446
+ def test_prefix_display_value(self):
447
+ """
448
+ Test that the `display` field is correctly populated.
449
+ """
450
+ url = reverse("ipam-api:prefix-list")
451
+ self.add_permissions("ipam.view_prefix")
452
+
453
+ response = self.client.get(f"{url}?depth=1", **self.header)
454
+ for p in response.data["results"]:
455
+ self.assertEqual(p["display"], f'{p["prefix"]}: {p["namespace"]["name"]}')
456
+
446
457
  def test_create_single_available_prefix(self):
447
458
  """
448
459
  Test retrieval of the first available prefix within a parent prefix.
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
  <link rel="icon" href="/projects/core/en/stable/assets/favicon.ico">
15
- <meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.31">
15
+ <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.34">
16
16
 
17
17
 
18
18
 
@@ -20,7 +20,7 @@
20
20
 
21
21
 
22
22
 
23
- <link rel="stylesheet" href="/projects/core/en/stable/assets/stylesheets/main.3cba04c6.min.css">
23
+ <link rel="stylesheet" href="/projects/core/en/stable/assets/stylesheets/main.35f28582.min.css">
24
24
 
25
25
 
26
26
  <link rel="stylesheet" href="/projects/core/en/stable/assets/stylesheets/palette.06af60db.min.css">
@@ -32,7 +32,7 @@
32
32
 
33
33
 
34
34
 
35
- <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>
35
+ <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 0zm-96 196.8V64h64v132.8c0 23.7 6.6 46.9 19 67.1l34.5 56.1h-171l34.5-56.1c12.4-20.2 19-43.4 19-67.1"/></svg>');}</style>
36
36
 
37
37
 
38
38
 
@@ -54,7 +54,7 @@
54
54
 
55
55
  <link rel="stylesheet" href="/projects/core/en/stable/assets/extra.css">
56
56
 
57
- <script>__md_scope=new URL("/projects/core/en/stable/",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
57
+ <script>__md_scope=new URL("/projects/core/en/stable/",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
58
58
 
59
59
 
60
60
 
@@ -98,7 +98,7 @@
98
98
  </a>
99
99
  <label class="md-header__button md-icon" for="__drawer">
100
100
 
101
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
101
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
102
102
  </label>
103
103
  <div class="md-header__title" data-md-component="header-title">
104
104
  <div class="md-header__ellipsis">
@@ -126,7 +126,7 @@
126
126
  <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
127
127
 
128
128
  <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
129
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5c-.84 0-1.65.15-2.39.42L12 2M3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29L3.34 7m.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14L3.36 17M20.65 7l-1.77 3.79a7.023 7.023 0 0 0-2.38-4.15l4.15.36m-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29L20.64 17M12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44L12 22Z"/></svg>
129
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
130
130
  </label>
131
131
 
132
132
 
@@ -136,7 +136,7 @@
136
136
  <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
137
137
 
138
138
  <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
139
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3 3.19.09m3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95 2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31Z"/></svg>
139
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
140
140
  </label>
141
141
 
142
142
 
@@ -144,13 +144,13 @@
144
144
 
145
145
 
146
146
 
147
- <script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
147
+ <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
148
148
 
149
149
 
150
150
 
151
151
  <label class="md-header__button md-icon" for="__search">
152
152
 
153
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
153
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
154
154
  </label>
155
155
  <div class="md-search" data-md-component="search" role="dialog">
156
156
  <label class="md-search__overlay" for="__search"></label>
@@ -159,20 +159,20 @@
159
159
  <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
160
160
  <label class="md-search__icon md-icon" for="__search">
161
161
 
162
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
162
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
163
163
 
164
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
164
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
165
165
  </label>
166
166
  <nav class="md-search__options" aria-label="Search">
167
167
 
168
168
  <a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
169
169
 
170
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7 0-.24-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91 1.61 0 2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08Z"/></svg>
170
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
171
171
  </a>
172
172
 
173
173
  <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
174
174
 
175
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
175
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
176
176
  </button>
177
177
  </nav>
178
178
 
@@ -197,7 +197,7 @@
197
197
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
198
198
  <div class="md-source__icon md-icon">
199
199
 
200
- <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>
200
+ <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.81"/></svg>
201
201
  </div>
202
202
  <div class="md-source__repository">
203
203
  GitHub
@@ -355,7 +355,7 @@
355
355
  <a href="https://github.com/nautobot/nautobot" title="Go to repository" class="md-source" data-md-component="source">
356
356
  <div class="md-source__icon md-icon">
357
357
 
358
- <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>
358
+ <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.81"/></svg>
359
359
  </div>
360
360
  <div class="md-source__repository">
361
361
  GitHub
@@ -8626,7 +8626,7 @@
8626
8626
  </div>
8627
8627
 
8628
8628
 
8629
- <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
8629
+ <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
8630
8630
 
8631
8631
  <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
8632
8632
  </div>
@@ -8667,7 +8667,7 @@
8667
8667
 
8668
8668
 
8669
8669
  <a href="https://blog.networktocode.com/blog/tags/nautobot" target="_blank" rel="noopener" title="Network to Code Blog" class="md-social__link">
8670
- <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>
8670
+ <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 64m0 352a64 64 0 1 1 128 0 64 64 0 1 1-128 0m32-256c159.1 0 288 128.9 288 288 0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224-17.7 0-32-14.3-32-32s14.3-32 32-32"/></svg>
8671
8671
  </a>
8672
8672
 
8673
8673
 
@@ -8675,7 +8675,7 @@
8675
8675
 
8676
8676
 
8677
8677
  <a href="https://www.youtube.com/playlist?list=PLjA0bhxgryJ2Ts4GJMDA-tPzVWEncv4pb" target="_blank" rel="noopener" title="Nautobot Videos" class="md-social__link">
8678
- <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>
8678
+ <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.305m-317.51 213.508V175.185l142.739 81.205z"/></svg>
8679
8679
  </a>
8680
8680
 
8681
8681
 
@@ -8683,7 +8683,7 @@
8683
8683
 
8684
8684
 
8685
8685
  <a href="https://www.networktocode.com/community/" target="_blank" rel="noopener" title="Network to Code Community" class="md-social__link">
8686
- <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>
8686
+ <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.1s21.16-47.06 47.06-47.06h47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06S448 171 448 196.9s-21.16 47.06-47.06 47.06h-47.06zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06S309 480 283.1 480s-47.06-21.16-47.06-47.06v-47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06s21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06z"/></svg>
8687
8687
  </a>
8688
8688
 
8689
8689
 
@@ -8691,7 +8691,7 @@
8691
8691
 
8692
8692
 
8693
8693
  <a href="https://github.com/nautobot/nautobot" target="_blank" rel="noopener" title="GitHub Repo" class="md-social__link">
8694
- <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>
8694
+ <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.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
8695
8695
  </a>
8696
8696
 
8697
8697
 
@@ -8699,7 +8699,7 @@
8699
8699
 
8700
8700
 
8701
8701
  <a href="https://twitter.com/networktocode" target="_blank" rel="noopener" title="Network to Code Twitter" class="md-social__link">
8702
- <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>
8702
+ <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.253"/></svg>
8703
8703
  </a>
8704
8704
 
8705
8705
  </div>
@@ -8714,10 +8714,10 @@
8714
8714
  </div>
8715
8715
 
8716
8716
 
8717
- <script id="__config" type="application/json">{"base": "/projects/core/en/stable/", "features": ["content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "/projects/core/en/stable/assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
8717
+ <script id="__config" type="application/json">{"base": "/projects/core/en/stable/", "features": ["content.code.copy", "content.tabs.link", "navigation.footer", "navigation.tabs", "navigation.tabs.sticky", "navigation.tracking", "search.highlight", "search.share", "search.suggest"], "search": "/projects/core/en/stable/assets/javascripts/workers/search.07f07601.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
8718
8718
 
8719
8719
 
8720
- <script src="/projects/core/en/stable/assets/javascripts/bundle.fe8b6f2b.min.js"></script>
8720
+ <script src="/projects/core/en/stable/assets/javascripts/bundle.56dfad97.min.js"></script>
8721
8721
 
8722
8722
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
8723
8723